You've already forked AstralRinth
forked from didirus/AstralRinth
Update master with new auth (#1236)
* Begin UI for threads and moderation overhaul * Hide close button on non-report threads * Fix review age coloring * Add project count * Remove action buttons from queue page and add queued date to project page * Hook up to actual data * Remove unused icon * Get up to 1000 projects in queue * prettier * more prettier * Changed all the things * lint * rebuild * Add omorphia * Workaround formatjs bug in ThreadSummary.vue * Fix notifications page on prod * Fix a few notifications and threads bugs * lockfile * Fix duplicate button styles * more fixes and polishing * More fixes * Remove legacy pages * More bugfixes * Add some error catching for reports and notifications * More error handling * fix lint * Add inbox links * Remove loading component and rename member header * Rely on threads always existing * Handle if project update notifs are not grouped * oops * Fix chips on notifications page * Import ModalModeration * finish threads * New authentication (#1234) * Initial new auth work * more auth pages * Finish most * more * fix on landing page * Finish everything but PATs + Sessions * fix threads merge bugs * fix cf pages ssr * fix most issues * Finish authentication * Fix merge --------- Co-authored-by: triphora <emma@modrinth.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<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>
|
||||
@@ -51,6 +51,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;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
v-else-if="
|
||||
!['resourcepack', 'shader'].includes(type) &&
|
||||
!(type === 'plugin' && search) &&
|
||||
!categories.some((x) => $tag.loaderData.dataPackLoaders.includes(x))
|
||||
!categories.some((x) => tags.loaderData.dataPackLoaders.includes(x))
|
||||
"
|
||||
class="environment"
|
||||
>
|
||||
@@ -47,57 +47,52 @@
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import InfoIcon from '~/assets/images/utils/info.svg'
|
||||
import ClientIcon from '~/assets/images/utils/client.svg'
|
||||
import GlobeIcon from '~/assets/images/utils/globe.svg'
|
||||
import ServerIcon from '~/assets/images/utils/server.svg'
|
||||
export default {
|
||||
components: {
|
||||
InfoIcon,
|
||||
ClientIcon,
|
||||
ServerIcon,
|
||||
GlobeIcon,
|
||||
|
||||
defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'mod',
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'mod',
|
||||
},
|
||||
serverSide: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
clientSide: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
typeOnly: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
alwaysShow: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
search: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
categories: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
serverSide: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
clientSide: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
typeOnly: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
alwaysShow: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
search: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
categories: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const tags = useTags()
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.environment {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div
|
||||
:class="{
|
||||
shown: actuallyShown,
|
||||
noblur: !$orElse($cosmetics.advancedRendering, true),
|
||||
noblur: !$orElse(cosmetics.advancedRendering, true),
|
||||
}"
|
||||
class="modal-overlay"
|
||||
@click="hide"
|
||||
@@ -38,6 +38,11 @@ export default {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const cosmetics = useCosmetics()
|
||||
|
||||
return { cosmetics }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shown: false,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Chips
|
||||
id="project-type"
|
||||
v-model="projectType"
|
||||
:items="$tag.projectTypes.map((x) => x.display)"
|
||||
:items="tags.projectTypes.map((x) => x.display)"
|
||||
/>
|
||||
<label for="name">
|
||||
<span class="label__title">Name<span class="required">*</span></span>
|
||||
@@ -86,9 +86,14 @@ export default {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const tags = useTags()
|
||||
|
||||
return { tags }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
projectType: this.$tag.projectTypes[0].display,
|
||||
projectType: this.tags.projectTypes[0].display,
|
||||
name: '',
|
||||
slug: '',
|
||||
description: '',
|
||||
@@ -100,7 +105,7 @@ export default {
|
||||
this.$refs.modal.hide()
|
||||
},
|
||||
getProjectType() {
|
||||
return this.$tag.projectTypes.find((x) => this.projectType === x.display)
|
||||
return this.tags.projectTypes.find((x) => this.projectType === x.display)
|
||||
},
|
||||
getClientSide() {
|
||||
switch (this.getProjectType().id) {
|
||||
@@ -137,6 +142,8 @@ export default {
|
||||
|
||||
const formData = new FormData()
|
||||
|
||||
const auth = await useAuth()
|
||||
|
||||
formData.append(
|
||||
'data',
|
||||
JSON.stringify({
|
||||
@@ -148,8 +155,8 @@ export default {
|
||||
initial_versions: [],
|
||||
team_members: [
|
||||
{
|
||||
user_id: this.$auth.user.id,
|
||||
name: this.$auth.user.username,
|
||||
user_id: auth.value.user.id,
|
||||
name: auth.value.user.username,
|
||||
role: 'Owner',
|
||||
},
|
||||
],
|
||||
@@ -167,7 +174,6 @@ export default {
|
||||
body: formData,
|
||||
headers: {
|
||||
'Content-Disposition': formData,
|
||||
Authorization: this.$auth.token,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -193,7 +199,7 @@ export default {
|
||||
stopLoading()
|
||||
},
|
||||
show() {
|
||||
this.projectType = this.$tag.projectTypes[0].display
|
||||
this.projectType = this.tags.projectTypes[0].display
|
||||
this.name = ''
|
||||
this.slug = ''
|
||||
this.description = ''
|
||||
|
||||
@@ -113,7 +113,6 @@ export default {
|
||||
await useBaseFetch(`project/${this.project.id}`, {
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
...this.$defaultHeaders(),
|
||||
})
|
||||
|
||||
this.$refs.modal.hide()
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<Multiselect
|
||||
id="report-type"
|
||||
v-model="reportType"
|
||||
:options="$tag.reportTypes"
|
||||
:options="tags.reportTypes"
|
||||
:custom-label="(value) => value.charAt(0).toUpperCase() + value.slice(1)"
|
||||
:multiple="false"
|
||||
:searchable="false"
|
||||
@@ -82,6 +82,11 @@ export default {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const tags = useTags()
|
||||
|
||||
return { tags }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reportType: '',
|
||||
@@ -110,7 +115,6 @@ export default {
|
||||
await useBaseFetch('report', {
|
||||
method: 'POST',
|
||||
body: data,
|
||||
...this.$defaultHeaders(),
|
||||
})
|
||||
|
||||
this.$refs.modal.hide()
|
||||
|
||||
@@ -128,14 +128,15 @@ export default {
|
||||
async proceed() {
|
||||
startLoading()
|
||||
try {
|
||||
await useBaseFetch(`user/${this.$auth.user.id}/payouts`, {
|
||||
const auth = await useAuth()
|
||||
|
||||
await useBaseFetch(`user/${auth.value.user.id}/payouts`, {
|
||||
method: 'POST',
|
||||
body: {
|
||||
amount: Number(this.amount.replace('$', '')),
|
||||
},
|
||||
...this.$defaultHeaders(),
|
||||
})
|
||||
await useAuth(this.$auth.token)
|
||||
await useAuth(auth.value.token)
|
||||
|
||||
this.$refs.modal.hide()
|
||||
} catch (err) {
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<nuxt-link :to="getProjectLink(project)" class="title-link">
|
||||
{{ project.title }}
|
||||
</nuxt-link>
|
||||
<template v-if="$tag.rejectedStatuses.includes(notification.body.new_status)">
|
||||
<template v-if="tags.rejectedStatuses.includes(notification.body.new_status)">
|
||||
has been <Badge :type="notification.body.new_status" />
|
||||
</template>
|
||||
<template v-else>
|
||||
@@ -106,6 +106,7 @@
|
||||
:raised="raised"
|
||||
:messages="getMessages()"
|
||||
class="thread-summary"
|
||||
:auth="auth"
|
||||
/>
|
||||
<div v-else-if="type === 'project_update'" class="version-list">
|
||||
<div
|
||||
@@ -221,7 +222,7 @@
|
||||
>
|
||||
<CheckIcon /> Mark as read
|
||||
</button>
|
||||
<CopyCode v-if="$cosmetics.developerMode" :text="notification.id" />
|
||||
<CopyCode v-if="cosmetics.developerMode" :text="notification.id" />
|
||||
</div>
|
||||
<div v-else class="input-group">
|
||||
<nuxt-link
|
||||
@@ -253,7 +254,7 @@
|
||||
>
|
||||
<CheckIcon /> Mark as read
|
||||
</button>
|
||||
<CopyCode v-if="$cosmetics.developerMode" :text="notification.id" />
|
||||
<CopyCode v-if="cosmetics.developerMode" :text="notification.id" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -301,8 +302,15 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const cosmetics = useCosmetics()
|
||||
const tags = useTags()
|
||||
|
||||
const type = computed(() =>
|
||||
!props.notification.body || props.notification.body.type === 'legacy_markdown'
|
||||
? null
|
||||
@@ -357,7 +365,6 @@ async function performAction(notification, actionIndex) {
|
||||
if (actionIndex !== null) {
|
||||
await useBaseFetch(`${notification.actions[actionIndex].action_route[1]}`, {
|
||||
method: notification.actions[actionIndex].action_route[0].toUpperCase(),
|
||||
...app.$defaultHeaders(),
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</p>
|
||||
<Categories
|
||||
:categories="
|
||||
categories.filter((x) => !hideLoaders || !$tag.loaders.find((y) => y.name === x))
|
||||
categories.filter((x) => !hideLoaders || !tags.loaders.find((y) => y.name === x))
|
||||
"
|
||||
:type="type"
|
||||
class="tags"
|
||||
@@ -209,6 +209,11 @@ export default {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const tags = useTags()
|
||||
|
||||
return { tags }
|
||||
},
|
||||
computed: {
|
||||
projectTypeDisplay() {
|
||||
return this.$getProjectTypeForDisplay(this.type, this.categories)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="$auth.user && showInvitation" class="universal-card information invited">
|
||||
<div v-if="showInvitation" class="universal-card information invited">
|
||||
<h2>Invitation to join project</h2>
|
||||
<p>
|
||||
You've been invited be a member of this project with the role of '{{ currentMember.role }}'.
|
||||
@@ -15,10 +15,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="
|
||||
$auth.user &&
|
||||
currentMember &&
|
||||
nags.filter((x) => x.condition).length > 0 &&
|
||||
(project.status === 'draft' || $tag.rejectedStatuses.includes(project.status))
|
||||
(project.status === 'draft' || tags.rejectedStatuses.includes(project.status))
|
||||
"
|
||||
class="author-actions universal-card"
|
||||
>
|
||||
@@ -155,6 +154,14 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
tags: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
setProcessing: {
|
||||
type: Function,
|
||||
default() {
|
||||
@@ -334,7 +341,7 @@ export default {
|
||||
},
|
||||
},
|
||||
{
|
||||
hide: !this.$tag.rejectedStatuses.includes(this.project.status),
|
||||
hide: !this.tags.rejectedStatuses.includes(this.project.status),
|
||||
condition: true,
|
||||
title: 'Resubmit for review',
|
||||
id: 'resubmit-for-review',
|
||||
@@ -363,8 +370,8 @@ export default {
|
||||
)
|
||||
},
|
||||
showInvitation() {
|
||||
if (this.allMembers && this.$auth) {
|
||||
const member = this.allMembers.find((x) => x.user.id === this.$auth.user.id)
|
||||
if (this.allMembers && this.auth) {
|
||||
const member = this.allMembers.find((x) => x.user.id === this.auth.user.id)
|
||||
return member && !member.accepted
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -98,9 +98,10 @@ const props = defineProps({
|
||||
})
|
||||
const emit = defineEmits(['switch-page'])
|
||||
|
||||
const data = useNuxtApp()
|
||||
const route = useRoute()
|
||||
|
||||
const tags = useTags()
|
||||
|
||||
const tempLoaders = new Set()
|
||||
let tempVersions = new Set()
|
||||
const tempReleaseChannels = new Set()
|
||||
@@ -119,7 +120,7 @@ tempVersions = Array.from(tempVersions)
|
||||
|
||||
const loaderFilters = shallowRef(Array.from(tempLoaders))
|
||||
const gameVersionFilters = shallowRef(
|
||||
data.$tag.gameVersions.filter((gameVer) => tempVersions.includes(gameVer.version))
|
||||
tags.value.gameVersions.filter((gameVer) => tempVersions.includes(gameVer.version))
|
||||
)
|
||||
const versionTypeFilters = shallowRef(Array.from(tempReleaseChannels))
|
||||
const includeSnapshots = ref(route.query.s === 'true')
|
||||
|
||||
@@ -63,10 +63,11 @@
|
||||
class="thread-summary"
|
||||
:raised="raised"
|
||||
:link="`/${moderation ? 'moderation' : 'dashboard'}/report/${report.id}`"
|
||||
:auth="auth"
|
||||
/>
|
||||
<div class="reporter-info">
|
||||
<ReportIcon class="inline-svg" /> Reported by
|
||||
<span v-if="$auth.user.id === report.reporterUser.id">you</span>
|
||||
<span v-if="auth.user.id === report.reporterUser.id">you</span>
|
||||
<nuxt-link v-else :to="`/user/${report.reporterUser.username}`" class="iconified-link">
|
||||
<Avatar
|
||||
:src="report.reporterUser.avatar_url"
|
||||
@@ -81,7 +82,7 @@
|
||||
<span v-tooltip="$dayjs(report.created).format('MMMM D, YYYY [at] h:mm A')">{{
|
||||
fromNow(report.created)
|
||||
}}</span>
|
||||
<CopyCode v-if="$cosmetics.developerMode" :text="report.id" class="report-id" />
|
||||
<CopyCode v-if="cosmetics.developerMode" :text="report.id" class="report-id" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -117,7 +118,13 @@ defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const cosmetics = useCosmetics()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -7,11 +7,16 @@
|
||||
:link-stack="breadcrumbsStack"
|
||||
/>
|
||||
<h2>Report details</h2>
|
||||
<ReportInfo :report="report" :show-thread="false" :show-message="false" />
|
||||
<ReportInfo :report="report" :show-thread="false" :show-message="false" :auth="auth" />
|
||||
</section>
|
||||
<section class="universal-card">
|
||||
<h2>Messages</h2>
|
||||
<ConversationThread :thread="thread" :report="report" :update-thread="updateThread" />
|
||||
<ConversationThread
|
||||
:thread="thread"
|
||||
:report="report"
|
||||
:update-thread="updateThread"
|
||||
:auth="auth"
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,10 +35,12 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const app = useNuxtApp()
|
||||
|
||||
const report = ref(null)
|
||||
|
||||
await fetchReport().then((result) => {
|
||||
@@ -41,7 +48,7 @@ await fetchReport().then((result) => {
|
||||
})
|
||||
|
||||
const { data: rawThread } = await useAsyncData(`thread/${report.value.thread_id}`, () =>
|
||||
useBaseFetch(`thread/${report.value.thread_id}`, app.$defaultHeaders())
|
||||
useBaseFetch(`thread/${report.value.thread_id}`)
|
||||
)
|
||||
const thread = computed(() => addReportMessage(rawThread.value, report.value))
|
||||
|
||||
@@ -52,7 +59,7 @@ async function updateThread(newThread) {
|
||||
|
||||
async function fetchReport() {
|
||||
const { data: rawReport } = await useAsyncData(`report/${props.reportId}`, () =>
|
||||
useBaseFetch(`report/${props.reportId}`, app.$defaultHeaders())
|
||||
useBaseFetch(`report/${props.reportId}`)
|
||||
)
|
||||
rawReport.value.item_id = rawReport.value.item_id.replace(/"/g, '')
|
||||
|
||||
@@ -67,7 +74,7 @@ async function fetchReport() {
|
||||
let users = []
|
||||
if (userIds.length > 0) {
|
||||
const { data: usersVal } = await useAsyncData(`users?ids=${JSON.stringify(userIds)}`, () =>
|
||||
useBaseFetch(`users?ids=${JSON.stringify(userIds)}`, app.$defaultHeaders())
|
||||
useBaseFetch(`users?ids=${encodeURIComponent(JSON.stringify(userIds))}`)
|
||||
)
|
||||
users = usersVal.value
|
||||
}
|
||||
@@ -75,7 +82,7 @@ async function fetchReport() {
|
||||
let version = null
|
||||
if (versionId) {
|
||||
const { data: versionVal } = await useAsyncData(`version/${versionId}`, () =>
|
||||
useBaseFetch(`version/${versionId}`, app.$defaultHeaders())
|
||||
useBaseFetch(`version/${versionId}`)
|
||||
)
|
||||
version = versionVal.value
|
||||
}
|
||||
@@ -89,7 +96,7 @@ async function fetchReport() {
|
||||
let project = null
|
||||
if (projectId) {
|
||||
const { data: projectVal } = await useAsyncData(`project/${projectId}`, () =>
|
||||
useBaseFetch(`project/${projectId}`, app.$defaultHeaders())
|
||||
useBaseFetch(`project/${projectId}`)
|
||||
)
|
||||
project = projectVal.value
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<ReportInfo
|
||||
v-for="report in reports.filter(
|
||||
(x) =>
|
||||
(moderation || x.reporterUser.id === $auth.user.id) &&
|
||||
(moderation || x.reporterUser.id === auth.user.id) &&
|
||||
(viewMode === 'open' ? x.open : !x.open)
|
||||
)"
|
||||
:key="report.id"
|
||||
@@ -11,6 +11,7 @@
|
||||
:thread="report.thread"
|
||||
:moderation="moderation"
|
||||
raised
|
||||
:auth="auth"
|
||||
class="universal-card recessed"
|
||||
/>
|
||||
</template>
|
||||
@@ -24,16 +25,16 @@ defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const app = useNuxtApp()
|
||||
|
||||
const viewMode = ref('open')
|
||||
const reports = ref([])
|
||||
|
||||
let { data: rawReports } = await useAsyncData('report', () =>
|
||||
useBaseFetch('report', app.$defaultHeaders())
|
||||
)
|
||||
let { data: rawReports } = await useAsyncData('report', () => useBaseFetch('report'))
|
||||
|
||||
rawReports = rawReports.value.map((report) => {
|
||||
report.item_id = report.item_id.replace(/"/g, '')
|
||||
@@ -53,13 +54,13 @@ const threadIds = [
|
||||
|
||||
const [{ data: users }, { data: versions }, { data: threads }] = await Promise.all([
|
||||
await useAsyncData(`users?ids=${JSON.stringify(userIds)}`, () =>
|
||||
useBaseFetch(`users?ids=${JSON.stringify(userIds)}`, app.$defaultHeaders())
|
||||
useBaseFetch(`users?ids=${encodeURIComponent(JSON.stringify(userIds))}`)
|
||||
),
|
||||
await useAsyncData(`versions?ids=${JSON.stringify(versionIds)}`, () =>
|
||||
useBaseFetch(`versions?ids=${JSON.stringify(versionIds)}`, app.$defaultHeaders())
|
||||
useBaseFetch(`versions?ids=${encodeURIComponent(JSON.stringify(versionIds))}`)
|
||||
),
|
||||
await useAsyncData(`threads?ids=${JSON.stringify(threadIds)}`, () =>
|
||||
useBaseFetch(`threads?ids=${JSON.stringify(threadIds)}`, app.$defaultHeaders())
|
||||
useBaseFetch(`threads?ids=${encodeURIComponent(JSON.stringify(threadIds))}`)
|
||||
),
|
||||
])
|
||||
|
||||
@@ -70,7 +71,7 @@ const versionProjects = versions.value.map((version) => version.project_id)
|
||||
const projectIds = [...new Set(reportedProjects.concat(versionProjects))]
|
||||
|
||||
const { data: projects } = await useAsyncData(`projects?ids=${JSON.stringify(projectIds)}`, () =>
|
||||
useBaseFetch(`projects?ids=${JSON.stringify(projectIds)}`, app.$defaultHeaders())
|
||||
useBaseFetch(`projects?ids=${encodeURIComponent(JSON.stringify(projectIds))}`)
|
||||
)
|
||||
|
||||
reports.value = rawReports.map((report) => {
|
||||
|
||||
@@ -23,10 +23,15 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const tags = useTags()
|
||||
|
||||
return { tags }
|
||||
},
|
||||
computed: {
|
||||
categoriesFiltered() {
|
||||
return this.$tag.categories
|
||||
.concat(this.$tag.loaders)
|
||||
return this.tags.categories
|
||||
.concat(this.tags.loaders)
|
||||
.filter(
|
||||
(x) =>
|
||||
this.categories.includes(x.name) && (!x.project_type || x.project_type === this.type)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<div v-if="$cosmetics.developerMode" class="thread-id">
|
||||
<div v-if="cosmetics.developerMode" class="thread-id">
|
||||
Thread ID: <CopyCode :text="thread.id" />
|
||||
</div>
|
||||
<div v-if="sortedMessages.length > 0" class="messages universal-card recessed">
|
||||
@@ -77,7 +77,7 @@
|
||||
>
|
||||
<SendIcon /> Send
|
||||
</button>
|
||||
<template v-if="currentMember && !isStaff($auth.user)">
|
||||
<template v-if="currentMember && !isStaff(auth.user)">
|
||||
<template v-if="isRejected(project)">
|
||||
<button
|
||||
v-if="replyBody"
|
||||
@@ -98,7 +98,7 @@
|
||||
<div class="spacer"></div>
|
||||
<div class="input-group extra-options">
|
||||
<template v-if="report">
|
||||
<template v-if="isStaff($auth.user)">
|
||||
<template v-if="isStaff(auth.user)">
|
||||
<button
|
||||
v-if="replyBody"
|
||||
class="iconified-button danger-button"
|
||||
@@ -112,7 +112,7 @@
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="project">
|
||||
<template v-if="isStaff($auth.user)">
|
||||
<template v-if="isStaff(auth.user)">
|
||||
<button
|
||||
v-if="replyBody"
|
||||
class="iconified-button brand-button"
|
||||
@@ -216,8 +216,13 @@ const props = defineProps({
|
||||
return null
|
||||
},
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
const app = useNuxtApp()
|
||||
const cosmetics = useCosmetics()
|
||||
|
||||
const members = computed(() => {
|
||||
const members = {}
|
||||
@@ -250,7 +255,7 @@ async function updateThreadLocal() {
|
||||
}
|
||||
let thread = null
|
||||
if (threadId) {
|
||||
thread = await useBaseFetch(`thread/${threadId}`, app.$defaultHeaders())
|
||||
thread = await useBaseFetch(`thread/${threadId}`)
|
||||
}
|
||||
props.updateThread(thread)
|
||||
}
|
||||
@@ -265,7 +270,6 @@ async function sendReply(status = null) {
|
||||
body: replyBody.value,
|
||||
},
|
||||
},
|
||||
...app.$defaultHeaders(),
|
||||
})
|
||||
replyBody.value = ''
|
||||
await updateThreadLocal()
|
||||
@@ -293,7 +297,6 @@ async function closeReport(reply) {
|
||||
body: {
|
||||
closed: true,
|
||||
},
|
||||
...app.$defaultHeaders(),
|
||||
})
|
||||
await updateThreadLocal()
|
||||
} catch (err) {
|
||||
|
||||
@@ -51,6 +51,10 @@ const props = defineProps({
|
||||
return []
|
||||
},
|
||||
},
|
||||
auth: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const app = useNuxtApp()
|
||||
@@ -60,7 +64,7 @@ const members = computed(() => {
|
||||
for (const member of props.thread.members) {
|
||||
members[member.id] = member
|
||||
}
|
||||
members[app.$auth.user.id] = app.$auth.user
|
||||
members[props.auth.user.id] = props.auth.user
|
||||
return members
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user