You've already forked AstralRinth
forked from didirus/AstralRinth
Move many things over from Knossos (and other rearrangements) (#102)
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
ref="img"
|
||||
:class="`avatar size-${size} ${circle ? 'circle' : ''} ${noShadow ? 'no-shadow' : ''} ${
|
||||
pixelated ? 'pixelated' : ''
|
||||
}`"
|
||||
} ${raised ? 'raised' : ''}`"
|
||||
:src="src"
|
||||
:alt="alt"
|
||||
:loading="loading"
|
||||
@@ -12,7 +12,9 @@
|
||||
/>
|
||||
<svg
|
||||
v-else
|
||||
:class="`avatar size-${size} ${circle ? 'circle' : ''} ${noShadow ? 'no-shadow' : ''}`"
|
||||
:class="`avatar size-${size} ${circle ? 'circle' : ''} ${noShadow ? 'no-shadow' : ''} ${
|
||||
raised ? 'raised' : ''
|
||||
}`"
|
||||
xml:space="preserve"
|
||||
fill-rule="evenodd"
|
||||
stroke-linecap="round"
|
||||
@@ -32,51 +34,48 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'sm',
|
||||
validator(value) {
|
||||
return ['xs', 'sm', 'md', 'lg', 'none'].includes(value)
|
||||
},
|
||||
},
|
||||
circle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
noShadow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loading: {
|
||||
type: String,
|
||||
default: 'lazy',
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const pixelated = ref(false)
|
||||
const img = ref(null)
|
||||
|
||||
defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
alt: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'sm',
|
||||
validator(value) {
|
||||
return ['xxs', 'xs', 'sm', 'md', 'lg', 'none'].includes(value)
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pixelated: false,
|
||||
}
|
||||
circle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
methods: {
|
||||
updatePixelated() {
|
||||
if (this.$refs.img && this.$refs.img.naturalWidth && this.$refs.img.naturalWidth <= 96) {
|
||||
this.pixelated = true
|
||||
} else {
|
||||
this.pixelated = false
|
||||
}
|
||||
},
|
||||
noShadow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loading: {
|
||||
type: String,
|
||||
default: 'lazy',
|
||||
},
|
||||
raised: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
function updatePixelated() {
|
||||
pixelated.value = !!(img.value && img.value.naturalWidth && img.value.naturalWidth <= 96)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -91,6 +90,12 @@ export default {
|
||||
max-width: var(--size) !important;
|
||||
max-height: var(--size) !important;
|
||||
|
||||
&.size-xxs {
|
||||
--size: 1.25rem;
|
||||
box-shadow: var(--shadow-inset), var(--shadow-card);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
&.size-xs {
|
||||
--size: 2.5rem;
|
||||
box-shadow: var(--shadow-inset), var(--shadow-card);
|
||||
@@ -128,5 +133,9 @@ export default {
|
||||
&.pixelated {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
&.raised {
|
||||
background-color: var(--color-raised-bg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,27 +1,38 @@
|
||||
<template>
|
||||
<span :class="'version-badge ' + color + ' type--' + type">
|
||||
<template v-if="color"> <span class="circle" /> {{ type }} </template>
|
||||
<template v-if="color"> <span class="circle" /> {{ capitalizeString(type) }}</template>
|
||||
|
||||
<!-- User roles -->
|
||||
<template v-else-if="type === 'admin'"> <ModrinthIcon /> Modrinth Team </template>
|
||||
<template v-else-if="type === 'moderator'"> <ScaleIcon /> Moderator </template>
|
||||
<template v-else-if="type === 'admin'"> <ModrinthIcon /> Modrinth Team</template>
|
||||
<template v-else-if="type === 'moderator'"> <ScaleIcon /> Moderator</template>
|
||||
<template v-else-if="type === 'creator'"><BoxIcon /> Creator</template>
|
||||
|
||||
<!-- Project statuses -->
|
||||
<template v-else-if="type === 'approved'"><ListIcon /> Listed</template>
|
||||
<template v-else-if="type === 'approved-general'"><CheckIcon /> Approved</template>
|
||||
<template v-else-if="type === 'unlisted'"><EyeOffIcon /> Unlisted</template>
|
||||
<template v-else-if="type === 'withheld'"><EyeOffIcon /> Withheld</template>
|
||||
<template v-else-if="type === 'private'"><LockIcon /> Private</template>
|
||||
<template v-else-if="type === 'scheduled'"> <CalendarIcon /> Scheduled </template>
|
||||
<template v-else-if="type === 'scheduled'"> <CalendarIcon /> Scheduled</template>
|
||||
<template v-else-if="type === 'draft'"><FileTextIcon /> Draft</template>
|
||||
<template v-else-if="type === 'archived'"> <ArchiveIcon /> Archived </template>
|
||||
<template v-else-if="type === 'archived'"> <ArchiveIcon /> Archived</template>
|
||||
<template v-else-if="type === 'rejected'"><XIcon /> Rejected</template>
|
||||
<template v-else-if="type === 'processing'"> <UpdatedIcon /> Under review </template>
|
||||
<template v-else-if="type === 'processing'"> <UpdatedIcon /> Under review</template>
|
||||
|
||||
<!-- Team members -->
|
||||
<template v-else-if="type === 'accepted'"><CheckIcon /> Accepted</template>
|
||||
<template v-else-if="type === 'pending'"> <UpdatedIcon /> Pending </template>
|
||||
<template v-else> <span class="circle" /> {{ type }} </template>
|
||||
<template v-else-if="type === 'pending'"> <UpdatedIcon /> Pending</template>
|
||||
|
||||
<!-- Transaction statuses (pending, processing reused) -->
|
||||
<template v-else-if="type === 'processed'"><CheckIcon /> Processed</template>
|
||||
<template v-else-if="type === 'failed'"><XIcon /> Failed</template>
|
||||
<template v-else-if="type === 'returned'"><XIcon /> Returned</template>
|
||||
|
||||
<!-- Report status -->
|
||||
<template v-else-if="type === 'closed'"> <XIcon /> Closed</template>
|
||||
|
||||
<!-- Other -->
|
||||
<template v-else> <span class="circle" /> {{ capitalizeString(type) }} </template>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -39,7 +50,8 @@ import {
|
||||
CheckIcon,
|
||||
LockIcon,
|
||||
CalendarIcon,
|
||||
} from '@/components'
|
||||
capitalizeString,
|
||||
} from '@'
|
||||
|
||||
defineProps({
|
||||
type: {
|
||||
@@ -52,7 +64,6 @@ defineProps({
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.version-badge {
|
||||
display: flex;
|
||||
@@ -75,8 +86,11 @@ defineProps({
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
&.type--closed,
|
||||
&.type--withheld,
|
||||
&.type--rejected,
|
||||
&.type--returned,
|
||||
&.type--failed,
|
||||
&.red {
|
||||
--badge-color: var(--color-red);
|
||||
}
|
||||
@@ -91,7 +105,8 @@ defineProps({
|
||||
|
||||
&.type--accepted,
|
||||
&.type--admin,
|
||||
&.type--success,
|
||||
&.type--processed,
|
||||
&.type--approved-general,
|
||||
&.green {
|
||||
--badge-color: var(--color-green);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { ExternalIcon, UnknownIcon } from '@/components'
|
||||
import { ExternalIcon, UnknownIcon } from '@'
|
||||
|
||||
import { computed } from 'vue'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { Button, DropdownIcon } from '@/components'
|
||||
import { Button, DropdownIcon } from '@'
|
||||
|
||||
import { reactive } from 'vue'
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckIcon, DropdownIcon } from '@/components'
|
||||
import { CheckIcon, DropdownIcon } from '@'
|
||||
</script>
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-for="item in items"
|
||||
:key="item"
|
||||
class="btn"
|
||||
:class="{ selected: selected === item }"
|
||||
:class="{ selected: selected === item, capitalize: capitalize }"
|
||||
@click="toggleItem(item)"
|
||||
>
|
||||
<CheckIcon v-if="selected === item" />
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckIcon, Button } from '@/components'
|
||||
import { CheckIcon, Button } from '@'
|
||||
</script>
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
@@ -36,6 +36,10 @@ export default defineComponent({
|
||||
default: (x) => x,
|
||||
type: Function,
|
||||
},
|
||||
capitalize: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
@@ -72,7 +76,9 @@ export default defineComponent({
|
||||
flex-wrap: wrap;
|
||||
|
||||
.btn {
|
||||
text-transform: capitalize;
|
||||
&.capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 1em;
|
||||
|
||||
21
lib/components/base/ConditionalNuxtLink.vue
Normal file
21
lib/components/base/ConditionalNuxtLink.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<router-link v-if="isLink" :to="to">
|
||||
<slot />
|
||||
</router-link>
|
||||
<span v-else>
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
to: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
isLink: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<button class="code" :class="{ copied }" title="Copy code to clipboard" @click="copyText">
|
||||
{{ text }}
|
||||
<span>{{ text }}</span>
|
||||
<CheckIcon v-if="copied" />
|
||||
<ClipboardCopyIcon v-else />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { CheckIcon, ClipboardCopyIcon } from '@/components'
|
||||
import { CheckIcon, ClipboardCopyIcon } from '@'
|
||||
</script>
|
||||
|
||||
<script>
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.code {
|
||||
display: flex;
|
||||
display: inline-flex;
|
||||
grid-gap: 0.5rem;
|
||||
font-family: var(--mono-font);
|
||||
font-size: var(--font-size-sm);
|
||||
@@ -47,6 +47,12 @@ export default {
|
||||
transition: opacity 0.5s ease-in-out, filter 0.2s ease-in-out, transform 0.05s ease-in-out,
|
||||
outline 0.2s ease-in-out;
|
||||
|
||||
span {
|
||||
max-width: 10rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
34
lib/components/base/DoubleIcon.vue
Normal file
34
lib/components/base/DoubleIcon.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div class="double-icon">
|
||||
<slot name="primary" />
|
||||
<div class="secondary">
|
||||
<slot name="secondary" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.double-icon {
|
||||
position: relative;
|
||||
height: fit-content;
|
||||
line-height: 0;
|
||||
|
||||
.secondary {
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
right: -4px;
|
||||
background-color: var(--color-bg);
|
||||
padding: var(--spacing-card-xs);
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1 / 1;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
line-height: 0;
|
||||
|
||||
svg {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -61,7 +61,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { DropdownIcon } from '@/components'
|
||||
import { DropdownIcon } from '@'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
A {{ type }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="!['resourcepack', 'shader'].includes(type) && !(type === 'plugin' && search)"
|
||||
v-else-if="
|
||||
!['resourcepack', 'shader'].includes(type) &&
|
||||
!(type === 'plugin' && search) &&
|
||||
!categories.includes('datapack')
|
||||
"
|
||||
class="environment"
|
||||
>
|
||||
<template v-if="clientSide === 'optional' && serverSide === 'optional'">
|
||||
@@ -44,7 +48,7 @@
|
||||
</span>
|
||||
</template>
|
||||
<script setup>
|
||||
import { GlobeIcon, ClientIcon, ServerIcon, InfoIcon } from '@/components'
|
||||
import { GlobeIcon, ClientIcon, ServerIcon, InfoIcon } from '@'
|
||||
</script>
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
@@ -80,6 +84,13 @@ export default defineComponent({
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
categories: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { fileIsValid } from '@/helpers/utils.js'
|
||||
import { fileIsValid } from '@'
|
||||
import { defineComponent } from 'vue'
|
||||
export default defineComponent({
|
||||
props: {
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<template>
|
||||
<Modal ref="modal" :header="`Report ${props.itemType}`" :noblur="noblur">
|
||||
<div class="modal-report">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
Modding should be safe for everyone, so we take abuse and malicious intent seriously at
|
||||
Modrinth. We want to hear about harmful content on the site that violates our
|
||||
<router-link to="/legal/terms">ToS</router-link>
|
||||
and
|
||||
<router-link to="/legal/rules">Rules</router-link>
|
||||
. Rest assured, we’ll keep your identifying information private.
|
||||
</p>
|
||||
<p v-if="props.itemType === 'project' || props.itemType === 'version'">
|
||||
Please <strong>do not</strong> use this to report bugs with the project itself. This form
|
||||
is only for submitting a report to Modrinth staff. If the project has an Issues link or a
|
||||
Discord invite, consider reporting it there.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="report-label" for="report-type">
|
||||
<span>
|
||||
<strong>Reason</strong>
|
||||
</span>
|
||||
</label>
|
||||
<DropdownSelect
|
||||
id="report-type"
|
||||
v-model="reportType"
|
||||
:options="props.reportTypes"
|
||||
default-value="Choose report type"
|
||||
class="multiselect"
|
||||
/>
|
||||
</div>
|
||||
<label class="report-label" for="additional-information">
|
||||
<strong>Additional information</strong>
|
||||
<span> Include links and images if possible. Markdown formatting is supported. </span>
|
||||
</label>
|
||||
<div>
|
||||
<div v-if="bodyViewType === 'source'" class="text-input textarea-wrapper">
|
||||
<Chips v-model="bodyViewType" class="separator" :items="['source', 'preview']" />
|
||||
<textarea id="body" v-model="body" spellcheck="true" />
|
||||
</div>
|
||||
<div v-else class="preview" v-html="renderString(body)"></div>
|
||||
</div>
|
||||
<div class="input-group push-right">
|
||||
<Button @click="cancel">
|
||||
<XIcon />
|
||||
Cancel
|
||||
</Button>
|
||||
<Button color="primary" @click="submitReport">
|
||||
<CheckIcon />
|
||||
Report
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Modal, Chips, XIcon, CheckIcon, DropdownSelect } from '@/components'
|
||||
import { renderString } from '@/helpers/parse.js'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
itemType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
itemId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
reportTypes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
submitReport: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
noblur: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const reportType = ref('')
|
||||
const body = ref('')
|
||||
const bodyViewType = ref('source')
|
||||
|
||||
const modal = ref(null)
|
||||
|
||||
function cancel() {
|
||||
reportType.value = ''
|
||||
body.value = ''
|
||||
bodyViewType.value = 'source'
|
||||
|
||||
modal.value.hide()
|
||||
}
|
||||
|
||||
function show() {
|
||||
modal.value.show()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.modal-report {
|
||||
padding: var(--gap-lg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.report-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
height: 12rem;
|
||||
gap: 1rem;
|
||||
|
||||
textarea {
|
||||
// here due to a bug in safari
|
||||
max-height: 9rem;
|
||||
}
|
||||
|
||||
.preview {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -115,6 +115,14 @@ function stopTimer(notif) {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
bottom: calc(var(--size-mobile-navbar-height, 15px) + 10px) !important;
|
||||
|
||||
&.browse-menu-open {
|
||||
bottom: calc(var(--size-mobile-navbar-height-expanded, 15px) + 10px) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notifs-enter-active,
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import PopoutMenu from '@/components/base/PopoutMenu.vue'
|
||||
import Button from '@/components/base/Button.vue'
|
||||
import { Button, PopoutMenu } from '@'
|
||||
|
||||
defineProps({
|
||||
options: {
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { GapIcon, LeftArrowIcon, RightArrowIcon } from '@/components'
|
||||
import { GapIcon, LeftArrowIcon, RightArrowIcon } from '@'
|
||||
</script>
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
@@ -77,7 +77,7 @@ export default defineComponent({
|
||||
pages() {
|
||||
let pages = []
|
||||
|
||||
if (this.count > 4) {
|
||||
if (this.count > 7) {
|
||||
if (this.page + 3 >= this.count) {
|
||||
pages = [
|
||||
1,
|
||||
@@ -88,7 +88,7 @@ export default defineComponent({
|
||||
this.count - 1,
|
||||
this.count,
|
||||
]
|
||||
} else if (this.page > 4) {
|
||||
} else if (this.page > 5) {
|
||||
pages = [1, '-', this.page - 1, this.page, this.page + 1, '-', this.count]
|
||||
} else {
|
||||
pages = [1, 2, 3, 4, 5, '-', this.count]
|
||||
@@ -103,6 +103,9 @@ export default defineComponent({
|
||||
methods: {
|
||||
switchPage(newPage) {
|
||||
this.$emit('switch-page', newPage)
|
||||
if (newPage !== null && newPage !== '' && !isNaN(newPage)) {
|
||||
this.$emit('switch-page', Math.min(Math.max(newPage, 1), this.count))
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
:server-side="serverSide"
|
||||
:type="projectTypeDisplay"
|
||||
:search="search"
|
||||
:categories="categories"
|
||||
/>
|
||||
</Categories>
|
||||
<div class="stats">
|
||||
@@ -65,7 +66,9 @@
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { formatNumber } from '@/helpers'
|
||||
import {
|
||||
Badge,
|
||||
HeartIcon,
|
||||
@@ -75,12 +78,13 @@ import {
|
||||
Avatar,
|
||||
Categories,
|
||||
EnvironmentIndicator,
|
||||
} from '@/components'
|
||||
import { formatNumber } from '@/helpers/utils.js'
|
||||
} from '@'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
dayjs.extend(relativeTime)
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
export default defineComponent({
|
||||
@@ -152,10 +156,6 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
hasModMessage: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
serverSide: {
|
||||
type: String,
|
||||
required: false,
|
||||
@@ -306,8 +306,7 @@ export default defineComponent({
|
||||
img,
|
||||
svg {
|
||||
border-radius: var(--radius-lg);
|
||||
border: 4px solid var(--color-raised-bg);
|
||||
border-bottom: none;
|
||||
box-shadow: -2px -2px 0 2px var(--color-raised-bg), 2px -2px 0 2px var(--color-raised-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import BisectIcon from '@/assets/external/bh.svg'
|
||||
import { BisectIcon } from '@'
|
||||
|
||||
const props = defineProps({
|
||||
external: {
|
||||
type: Boolean,
|
||||
@@ -38,6 +40,7 @@ const props = defineProps({
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const target = computed(() => (props.external ? '_blank' : '_self'))
|
||||
</script>
|
||||
|
||||
|
||||
@@ -33,5 +33,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g></svg
|
||||
><svg
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
class="rotate inner"
|
||||
width="100%"
|
||||
height="100%"
|
||||
@@ -45,9 +46,7 @@
|
||||
viewBox="0 0 590 591"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve"
|
||||
xmlns:serif="http://www.serif.com/"
|
||||
style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 2"
|
||||
>
|
||||
<g transform="matrix(1,0,0,1,652.392,-0.400578)">
|
||||
@@ -72,12 +71,6 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AnimatedLogo',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
div {
|
||||
height: 5rem;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
stroke-miterlimit="2"
|
||||
clip-rule="evenodd"
|
||||
viewBox="0 0 3307 593"
|
||||
:class="{ animate: animate }"
|
||||
:class="{ animate }"
|
||||
>
|
||||
<path
|
||||
fill-rule="nonzero"
|
||||
@@ -30,16 +30,13 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TextLogo',
|
||||
props: {
|
||||
animate: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
<script setup>
|
||||
defineProps({
|
||||
animate: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { defineProps, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { Bar } from 'vue-chartjs'
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
@@ -1,43 +1,76 @@
|
||||
// Base content
|
||||
export { default as Avatar } from './base/Avatar.vue'
|
||||
export { default as Badge } from './base/Badge.vue'
|
||||
export { default as Button } from './base/Button.vue'
|
||||
export { default as Card } from './base/Card.vue'
|
||||
export { default as Checkbox } from './base/Checkbox.vue'
|
||||
export { default as Chips } from './base/Chips.vue'
|
||||
export { default as ConditionalNuxtLink } from './base/ConditionalNuxtLink.vue'
|
||||
export { default as CopyCode } from './base/CopyCode.vue'
|
||||
export { default as DoubleIcon } from './base/DoubleIcon.vue'
|
||||
export { default as DropArea } from './base/DropArea.vue'
|
||||
export { default as DropdownSelect } from './base/DropdownSelect.vue'
|
||||
export { default as EnvironmentIndicator } from './base/EnvironmentIndicator.vue'
|
||||
export { default as FileInput } from './base/FileInput.vue'
|
||||
export { default as Notifications } from './base/Notifications.vue'
|
||||
export { default as OverflowMenu } from './base/OverflowMenu.vue'
|
||||
export { default as Page } from './base/Page.vue'
|
||||
export { default as Slider } from './base/Slider.vue'
|
||||
export { default as AnimatedLogo } from './brand/AnimatedLogo.vue'
|
||||
export { default as TextLogo } from './brand/TextLogo.vue'
|
||||
export { default as Pagination } from './base/Pagination.vue'
|
||||
export { default as Modal } from './base/Modal.vue'
|
||||
export { default as ModalReport } from './base/ModalReport.vue'
|
||||
export { default as PopoutMenu } from './base/PopoutMenu.vue'
|
||||
export { default as ProjectCard } from './base/ProjectCard.vue'
|
||||
export { default as Promotion } from './base/Promotion.vue'
|
||||
export { default as EnvironmentIndicator } from './base/EnvironmentIndicator.vue'
|
||||
export { default as DropdownSelect } from './base/DropdownSelect.vue'
|
||||
export { default as FileInput } from './base/FileInput.vue'
|
||||
export { default as DropArea } from './base/DropArea.vue'
|
||||
export { default as Slider } from './base/Slider.vue'
|
||||
export { default as Toggle } from './base/Toggle.vue'
|
||||
export { default as CopyCode } from './base/CopyCode.vue'
|
||||
export { default as Notifications } from './base/Notifications.vue'
|
||||
export { default as ModalConfirm } from './base/ModalConfirm.vue'
|
||||
export { default as Breadcrumbs } from './base/Breadcrumbs.vue'
|
||||
export { default as ShareModal } from './base/ShareModal.vue'
|
||||
export { default as LineChart } from './base/LineChart.vue'
|
||||
export { default as PieChart } from './base/PieChart.vue'
|
||||
export { default as BarChart } from './base/BarChart.vue'
|
||||
export { default as SearchDropdown } from './search/SearchDropdown.vue'
|
||||
|
||||
export { default as Categories } from './search/Categories.vue'
|
||||
export { default as SearchFilter } from './search/SearchFilter.vue'
|
||||
// Branding
|
||||
export { default as ModrinthIcon } from '@/assets/branding/logo.svg?component'
|
||||
export { default as AnimatedLogo } from './brand/AnimatedLogo.vue'
|
||||
export { default as TextLogo } from './brand/TextLogo.vue'
|
||||
export { default as FourOhFourNotFound } from '@/assets/branding/404.svg?component'
|
||||
|
||||
// Charts
|
||||
export { default as BarChart } from './chart/BarChart.vue'
|
||||
export { default as LineChart } from './chart/LineChart.vue'
|
||||
export { default as PieChart } from './chart/PieChart.vue'
|
||||
|
||||
// Modals
|
||||
export { default as Modal } from './modal/Modal.vue'
|
||||
export { default as ConfirmModal } from './modal/ConfirmModal.vue'
|
||||
export { default as ReportModal } from './modal/ReportModal.vue'
|
||||
export { default as ShareModal } from './modal/ShareModal.vue'
|
||||
|
||||
// Navigation
|
||||
export { default as Breadcrumbs } from './nav/Breadcrumbs.vue'
|
||||
export { default as NavItem } from './nav/NavItem.vue'
|
||||
export { default as NavRow } from './nav/NavRow.vue'
|
||||
export { default as NavStack } from './nav/NavStack.vue'
|
||||
|
||||
export { default as PopoutMenu } from './base/PopoutMenu.vue'
|
||||
export { default as OverflowMenu } from './base/OverflowMenu.vue'
|
||||
// Search
|
||||
export { default as Categories } from './search/Categories.vue'
|
||||
export { default as SearchDropdown } from './search/SearchDropdown.vue'
|
||||
export { default as SearchFilter } from './search/SearchFilter.vue'
|
||||
|
||||
// External Icons
|
||||
export { default as SSODiscordIcon } from '@/assets/external/sso/discord.svg?component'
|
||||
export { default as SSOGitHubIcon } from '@/assets/external/sso/github.svg?component'
|
||||
export { default as SSOGitLabIcon } from '@/assets/external/sso/gitlab.svg?component'
|
||||
export { default as SSOGoogleIcon } from '@/assets/external/sso/google.svg?component'
|
||||
export { default as SSOMicrosoftIcon } from '@/assets/external/sso/microsoft.svg?component'
|
||||
export { default as SSOSteamIcon } from '@/assets/external/sso/steam.svg?component'
|
||||
export { default as AppleIcon } from '@/assets/external/apple.svg?component'
|
||||
export { default as BisectIcon } from '@/assets/external/bh.svg?component'
|
||||
export { default as BuyMeACoffeeIcon } from '@/assets/external/bmac.svg?component'
|
||||
export { default as DiscordIcon } from '@/assets/external/discord.svg?component'
|
||||
export { default as KoFiIcon } from '@/assets/external/kofi.svg?component'
|
||||
export { default as MastodonIcon } from '@/assets/external/mastodon.svg?component'
|
||||
export { default as OpenCollectiveIcon } from '@/assets/external/opencollective.svg?component'
|
||||
export { default as PatreonIcon } from '@/assets/external/patreon.svg?component'
|
||||
export { default as PayPalIcon } from '@/assets/external/paypal.svg?component'
|
||||
export { default as RedditIcon } from '@/assets/external/reddit.svg?component'
|
||||
export { default as TwitterIcon } from '@/assets/external/twitter.svg?component'
|
||||
export { default as WindowsIcon } from '@/assets/external/windows.svg?component'
|
||||
|
||||
// Icons
|
||||
export { default as AlignLeftIcon } from '@/assets/icons/align-left.svg?component'
|
||||
export { default as ArchiveIcon } from '@/assets/icons/archive.svg?component'
|
||||
export { default as AsteriskIcon } from '@/assets/icons/asterisk.svg?component'
|
||||
@@ -49,6 +82,7 @@ export { default as BoxIcon } from '@/assets/icons/box.svg?component'
|
||||
export { default as CalendarIcon } from '@/assets/icons/calendar.svg?component'
|
||||
export { default as ChartIcon } from '@/assets/icons/chart.svg?component'
|
||||
export { default as CheckIcon } from '@/assets/icons/check.svg?component'
|
||||
export { default as CheckCheckIcon } from '@/assets/icons/check-check.svg?component'
|
||||
export { default as CheckCircleIcon } from '@/assets/icons/check-circle.svg?component'
|
||||
export { default as ChevronLeftIcon } from '@/assets/icons/chevron-left.svg?component'
|
||||
export { default as ChevronRightIcon } from '@/assets/icons/chevron-right.svg?component'
|
||||
@@ -89,14 +123,20 @@ export { default as HomeIcon } from '@/assets/icons/home.svg?component'
|
||||
export { default as ImageIcon } from '@/assets/icons/image.svg?component'
|
||||
export { default as InfoIcon } from '@/assets/icons/info.svg?component'
|
||||
export { default as IssuesIcon } from '@/assets/icons/issues.svg?component'
|
||||
export { default as KeyIcon } from '@/assets/icons/key.svg?component'
|
||||
export { default as LanguagesIcon } from '@/assets/icons/languages.svg?component'
|
||||
export { default as LeftArrowIcon } from '@/assets/icons/left-arrow.svg?component'
|
||||
export { default as LibraryIcon } from '@/assets/icons/library.svg?component'
|
||||
export { default as LightBulbIcon } from '@/assets/icons/light-bulb.svg?component'
|
||||
export { default as LinkIcon } from '@/assets/icons/link.svg?component'
|
||||
export { default as ListIcon } from '@/assets/icons/list.svg?component'
|
||||
export { default as ListEndIcon } from '@/assets/icons/list-end.svg?component'
|
||||
export { default as LockIcon } from '@/assets/icons/lock.svg?component'
|
||||
export { default as LogInIcon } from '@/assets/icons/log-in.svg?component'
|
||||
export { default as LogOutIcon } from '@/assets/icons/log-out.svg?component'
|
||||
export { default as MailIcon } from '@/assets/icons/mail.svg?component'
|
||||
export { default as MessageIcon } from '@/assets/icons/message.svg?component'
|
||||
export { default as MicrophoneIcon } from '@/assets/icons/microphone.svg?component'
|
||||
export { default as MoonIcon } from '@/assets/icons/moon.svg?component'
|
||||
export { default as MoreHorizontalIcon } from '@/assets/icons/more-horizontal.svg?component'
|
||||
export { default as MoreVerticalIcon } from '@/assets/icons/more-vertical.svg?component'
|
||||
@@ -104,6 +144,9 @@ export { default as OmorphiaIcon } from '@/assets/icons/omorphia.svg?component'
|
||||
export { default as PaintBrushIcon } from '@/assets/icons/paintbrush.svg?component'
|
||||
export { default as PlayIcon } from '@/assets/icons/play.svg?component'
|
||||
export { default as PlusIcon } from '@/assets/icons/plus.svg?component'
|
||||
export { default as RadioButtonIcon } from '@/assets/icons/radio-button.svg?component'
|
||||
export { default as RadioButtonChecked } from '@/assets/icons/radio-button-checked.svg?component'
|
||||
export { default as ReplyIcon } from '@/assets/icons/reply.svg?component'
|
||||
export { default as ReportIcon } from '@/assets/icons/report.svg?component'
|
||||
export { default as RightArrowIcon } from '@/assets/icons/right-arrow.svg?component'
|
||||
export { default as SaveIcon } from '@/assets/icons/save.svg?component'
|
||||
@@ -112,8 +155,11 @@ export { default as SearchIcon } from '@/assets/icons/search.svg?component'
|
||||
export { default as SendIcon } from '@/assets/icons/send.svg?component'
|
||||
export { default as ServerIcon } from '@/assets/icons/server.svg?component'
|
||||
export { default as SettingsIcon } from '@/assets/icons/settings.svg?component'
|
||||
export { default as ShareIcon } from '@/assets/icons/share.svg?component'
|
||||
export { default as ShieldIcon } from '@/assets/icons/shield.svg?component'
|
||||
export { default as SlashIcon } from '@/assets/icons/slash.svg?component'
|
||||
export { default as SortAscendingIcon } from '@/assets/icons/sort-asc.svg?component'
|
||||
export { default as SortDescendingIcon } from '@/assets/icons/sort-desc.svg?component'
|
||||
export { default as StarIcon } from '@/assets/icons/star.svg?component'
|
||||
export { default as StopCircleIcon } from '@/assets/icons/stop-circle.svg?component'
|
||||
export { default as SunIcon } from '@/assets/icons/sun.svg?component'
|
||||
@@ -136,11 +182,3 @@ export { default as VersionIcon } from '@/assets/icons/version.svg?component'
|
||||
export { default as WikiIcon } from '@/assets/icons/wiki.svg?component'
|
||||
export { default as XIcon } from '@/assets/icons/x.svg?component'
|
||||
export { default as XCircleIcon } from '@/assets/icons/x-circle.svg?component'
|
||||
export { default as MailIcon } from '@/assets/icons/mail.svg?component'
|
||||
export { default as ShareIcon } from '@/assets/icons/share.svg?component'
|
||||
|
||||
export { default as MastodonIcon } from '@/assets/external/mastodon.svg?component'
|
||||
export { default as RedditIcon } from '@/assets/external/reddit.svg?component'
|
||||
export { default as TwitterIcon } from '@/assets/external/twitter.svg?component'
|
||||
|
||||
export { default as ModrinthIcon } from '@/assets/branding/logo.svg?component'
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<Modal ref="modal" :header="props.title" :noblur="noblur">
|
||||
<Modal ref="modal" :header="title" :noblur="noblur">
|
||||
<div class="modal-delete">
|
||||
<div class="markdown-body" v-html="renderString(props.description)" />
|
||||
<label v-if="props.hasToType" for="confirmation" class="confirmation-label">
|
||||
<div class="markdown-body" v-html="renderString(description)" />
|
||||
<label v-if="hasToType" for="confirmation" class="confirmation-label">
|
||||
<span>
|
||||
<strong>To verify, type</strong>
|
||||
<em class="confirmation-text">{{ props.confirmationText }}</em>
|
||||
<em class="confirmation-text">{{ confirmationText }}</em>
|
||||
<strong>below:</strong>
|
||||
</span>
|
||||
</label>
|
||||
<div class="confirmation-input">
|
||||
<input
|
||||
v-if="props.hasToType"
|
||||
v-if="hasToType"
|
||||
id="confirmation"
|
||||
v-model="confirmation_typed"
|
||||
type="text"
|
||||
@@ -26,7 +26,7 @@
|
||||
</button>
|
||||
<button class="btn btn-danger" :disabled="action_disabled" @click="proceed">
|
||||
<TrashIcon />
|
||||
{{ props.proceedLabel }}
|
||||
{{ proceedLabel }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -34,8 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { renderString } from '@/helpers/parse'
|
||||
import { XIcon, TrashIcon, Modal } from '@/components'
|
||||
import { Modal, TrashIcon, XIcon, renderString } from '@'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -32,7 +32,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { XIcon } from '@/components'
|
||||
import { XIcon } from '@'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
123
lib/components/modal/ReportModal.vue
Normal file
123
lib/components/modal/ReportModal.vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<Modal ref="modal" :header="`Report ${itemType}`" :noblur="noblur">
|
||||
<div class="modal-report universal-labels">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
Modding should be safe for everyone, so we take abuse and malicious intent seriously at
|
||||
Modrinth. We want to hear about harmful content on the site that violates our
|
||||
<router-link to="/legal/terms">ToS</router-link> and
|
||||
<router-link to="/legal/rules">Rules</router-link>. Rest assured, we'll keep your
|
||||
identifying information private.
|
||||
</p>
|
||||
<p v-if="itemType === 'project' || itemType === 'version'">
|
||||
Please <strong>do not</strong> use this to report bugs with the project itself. This form
|
||||
is only for submitting a report to Modrinth staff. If the project has an Issues link or a
|
||||
Discord invite, consider reporting it there.
|
||||
</p>
|
||||
</div>
|
||||
<label for="report-type">
|
||||
<span class="label__title">Reason</span>
|
||||
</label>
|
||||
<DropdownSelect
|
||||
id="report-type"
|
||||
v-model="reportType"
|
||||
name="report-type"
|
||||
:options="reportTypes"
|
||||
:display-name="capitalizeString"
|
||||
default-value="Choose report type"
|
||||
class="multiselect"
|
||||
/>
|
||||
<label for="report-body">
|
||||
<span class="label__title">Additional information</span>
|
||||
<span class="label__description markdown-body">
|
||||
Please provide additional context about your report. Include links and images if possible.
|
||||
<strong>Empty reports will be closed.</strong> This editor supports
|
||||
<a href="https://docs.modrinth.com/markdown" target="_blank">Markdown formatting</a>.
|
||||
</span>
|
||||
</label>
|
||||
<Chips v-model="bodyViewType" class="separator" :items="['source', 'preview']" />
|
||||
<div class="text-input textarea-wrapper">
|
||||
<textarea v-if="bodyViewType === 'source'" id="body" v-model="body" spellcheck="true" />
|
||||
<div v-else class="preview" v-html="renderString(body)" />
|
||||
</div>
|
||||
<div class="input-group push-right">
|
||||
<Button @click="cancel">
|
||||
<XIcon />
|
||||
Cancel
|
||||
</Button>
|
||||
<Button color="primary" @click="submitReport">
|
||||
<CheckIcon />
|
||||
Report
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Chips, DropdownSelect, Modal, CheckIcon, XIcon, capitalizeString, renderString } from '@'
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineProps({
|
||||
itemType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
itemId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
reportTypes: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
submitReport: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
noblur: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const reportType = ref('')
|
||||
const body = ref('')
|
||||
const bodyViewType = ref('source')
|
||||
|
||||
const modal = ref(null)
|
||||
|
||||
function cancel() {
|
||||
reportType.value = ''
|
||||
body.value = ''
|
||||
bodyViewType.value = 'source'
|
||||
|
||||
modal.value.hide()
|
||||
}
|
||||
|
||||
function show() {
|
||||
modal.value.show()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.modal-report {
|
||||
padding: var(--gap-lg);
|
||||
|
||||
.textarea-wrapper {
|
||||
height: 10rem;
|
||||
|
||||
:first-child {
|
||||
max-height: 8rem;
|
||||
transform: translateY(1rem);
|
||||
}
|
||||
}
|
||||
|
||||
.preview {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
TwitterIcon,
|
||||
MastodonIcon,
|
||||
RedditIcon,
|
||||
} from '@/components'
|
||||
} from '@'
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ChevronRightIcon } from '@/components'
|
||||
import { ChevronRightIcon } from '@'
|
||||
defineProps({
|
||||
linkStack: {
|
||||
type: Array,
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { Button } from '@/components'
|
||||
import { Button } from '@'
|
||||
|
||||
defineProps({
|
||||
link: {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
<script setup>
|
||||
defineProps({})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="omorphia__navstack">
|
||||
<slot />
|
||||
|
||||
@@ -9,23 +9,16 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { formatCategory } from '@/helpers/utils.js'
|
||||
</script>
|
||||
<script>
|
||||
export default {
|
||||
name: 'Categories',
|
||||
props: {
|
||||
categories: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
import { formatCategory } from '@'
|
||||
|
||||
defineProps({
|
||||
categories: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatCategory,
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { Avatar, Button, XIcon, SearchIcon } from '@/components'
|
||||
import { Avatar, Button, XIcon, SearchIcon } from '@'
|
||||
|
||||
const props = defineProps({
|
||||
options: {
|
||||
|
||||
@@ -15,50 +15,48 @@
|
||||
</Checkbox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import Checkbox from '@/components/base/Checkbox.vue'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Checkbox,
|
||||
<script setup>
|
||||
import { Checkbox } from '@'
|
||||
|
||||
defineProps({
|
||||
facetName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
props: {
|
||||
facetName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
displayName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeFilters: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
displayName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
emits: ['toggle'],
|
||||
methods: {
|
||||
toggle() {
|
||||
this.$emit('toggle', this.facetName)
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeFilters: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['toggle'])
|
||||
|
||||
function toggle() {
|
||||
emit('toggle', this.facetName)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
:deep(.filter-text) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 1rem;
|
||||
|
||||
svg {
|
||||
margin-right: 0.25rem;
|
||||
width: 1rem;
|
||||
@@ -66,6 +64,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user