mirror of
https://github.com/modrinth/code.git
synced 2026-09-03 13:36:48 +00:00
project disclosures frontend (#6955)
* begin project disclosures * new project settings header * begin disclosure settings, edit content rules * togglecards * update phrasing of the rules, prepr * more disclosure settings structuring * add functionality toggle * implement functionality with staging api * improve project settings head titles * feat(labrinth): project disclosures model * feat(labrinth): project disclosures database model * feat(labrinth): project disclosures get endpoint * feat(labrinth): censor user ids if set by moderator * feat(labrinth): wrap disclosures in struct * feat(labrinth): edit project disclosures endpoint * style(labrinth): cargo fmt * style(labrinth): fix typo * feat(labrinth): add fields for ai content disclosure * fix(labrinth): field typo * chore(labrinth): update query cache * feat(labrinth): index disclosures in search * refactor(labrinth): use enum instead of bools * feat(labrinth): trigger incremental index on disclosure change * feat(labrinth): change archived status to disclosure * feat(labrinth): use disclosure for archival status * fix(labrinth): error type for deserialization * fix(labrinth): migration timestamp * fix(labrinth): add disclosures to elasticsearch schema * disclosures in search * update photosensitivity warning copy * update archiving, move general project settings to v3 (start redesign there), use project id lookups for stable cache keys, advanced in server search * blue archive banner * display AI use types * improve labels * add modrinth to link * add placeholder missing disclosure report type * add AI metadata checking to block image uploads with notice * update copy * update section 4 of rules * Update rule 6 layout * fix(labrinth): don't remove archival disclosure when changing status via v3 api * feat(labrinth): derive str for ai usages and telemtry consent * feat(labrinth): include ai usages and telemetry consent in disclosure types * Update moderation checklist (#7056) * fix: missing delphi severity (#7054) * Utils nav, new disclosures stage, ai button in rules * add prefix to collect * Finish up new disclosures stage * update r4 messages * new r4 msg, update showcase clarity message * fix: version upload failing to detect mrpack loader (#7063) * fix: mrpack exporting with zip64 (#7064) * fix: action bar max width (#7048) * fix: action bar max width * fix: width * changelog * Rule placeholders with subsections & anchors, update messages. * update new messages to account for new rule and placeholder layout * Add nag for content disclosures --------- Co-authored-by: ThatGravyBoat <gravy@thatgravyboat.tech> Co-authored-by: chyzman <chyzalt@gmail.com> Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> * prepr * refactor(labrinth): move disclosure parsing to document creation * fix(labrinth): prevent removing moderator added archival disclosures * fix(labrinth): dedupe ai usages * fix(labrinth): auth logic on archived disclosure removal * feat(labrinth): add interactions field * style(labrinth): cargo fmt * feat(labrinth): granular disclosure locking * add 5.8, move 5.9, update messages and placeholders accordingly. * move disclosures stage earlier * include consent model info in telemetry disclosure msgs * prepr + update date * typo * qa pass * search suboptions * add empty state * checkboxes in column * persistent advanced filters * blog draft * prepr * support soft deletion * reload instead of optimistically updating * update blog * TOS update + minor verbiage adjustment * 45 day grace --------- Co-authored-by: sychic <47618543+Sychic@users.noreply.github.com> Co-authored-by: coolbot <76798835+coolbot100s@users.noreply.github.com> Co-authored-by: ThatGravyBoat <gravy@thatgravyboat.tech> Co-authored-by: chyzman <chyzalt@gmail.com> Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com>
This commit is contained in:
co-authored by
ThatGravyBoat
chyzman
Truman Gao
sychic
coolbot
parent
06b7c44dcc
commit
755825b09a
+146
@@ -0,0 +1,146 @@
|
||||
<script setup lang="ts">
|
||||
import { CircleSlashIcon, LockIcon, LockOpenIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
normalizeChildren,
|
||||
SettingsInlineWarning,
|
||||
SettingsToggleCard,
|
||||
} from '@modrinth/ui'
|
||||
import type { Component } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import DisclosureUpdatedBy from './DisclosureUpdatedBy.vue'
|
||||
import type { DisclosureCardMetaProps, DisclosureLockStatus } from './types'
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
|
||||
const props = defineProps<
|
||||
DisclosureCardMetaProps & {
|
||||
title: string
|
||||
icon?: Component
|
||||
description?: string
|
||||
}
|
||||
>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
setLockStatus: [status: DisclosureLockStatus]
|
||||
}>()
|
||||
|
||||
const enabled = defineModel<boolean>({ required: true })
|
||||
|
||||
const resolvedLockStatus = computed(() => props.lockStatus ?? 'unlocked')
|
||||
|
||||
const LOCK_STATUSES = [
|
||||
{ status: 'unlocked', label: 'Unlocked' },
|
||||
{ status: 'cannot_disable', label: 'Cannot disable' },
|
||||
{ status: 'fully_locked', label: 'Fully locked' },
|
||||
] as const
|
||||
|
||||
const messages = defineMessages({
|
||||
cannotDisableWarning: {
|
||||
id: 'project.settings.disclosures.lock-status.cannot-disable.warning',
|
||||
defaultMessage:
|
||||
'Please <contact-support-link>contact support</contact-support-link> if this disclosure needs to be removed.',
|
||||
},
|
||||
fullyLockedWarning: {
|
||||
id: 'project.settings.disclosures.lock-status.fully-locked.warning',
|
||||
defaultMessage:
|
||||
'Please <contact-support-link>contact support</contact-support-link> if this disclosure needs to be edited or removed.',
|
||||
},
|
||||
disabledLockedWarning: {
|
||||
id: 'project.settings.disclosures.lock-status.disabled.warning',
|
||||
defaultMessage:
|
||||
'This disclosure has been locked by the moderators. Please <contact-support-link>contact support</contact-support-link> if you believe this is in error.',
|
||||
},
|
||||
})
|
||||
|
||||
const lockWarningMessage = computed(() => {
|
||||
if (resolvedLockStatus.value === 'cannot_disable') {
|
||||
return enabled.value ? messages.cannotDisableWarning : null
|
||||
}
|
||||
if (resolvedLockStatus.value === 'fully_locked') {
|
||||
return enabled.value ? messages.fullyLockedWarning : messages.disabledLockedWarning
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
const showLockWarning = computed(() => !!lockWarningMessage.value)
|
||||
|
||||
const showModeratorLockControls = computed(() => !!props.showLockControls)
|
||||
|
||||
const showFooter = computed(
|
||||
() => !!props.updatedAt || showModeratorLockControls.value || showLockWarning.value,
|
||||
)
|
||||
|
||||
function setLockStatus(status: DisclosureLockStatus) {
|
||||
if (resolvedLockStatus.value === status) return
|
||||
emit('setLockStatus', status)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SettingsToggleCard
|
||||
v-model="enabled"
|
||||
:disabled="disabled"
|
||||
:toggle-disabled="toggleDisabled"
|
||||
:icon="icon"
|
||||
:title="title"
|
||||
:description="description"
|
||||
>
|
||||
<slot />
|
||||
<template v-if="$slots.expanded" #expanded>
|
||||
<slot name="expanded" />
|
||||
</template>
|
||||
<template v-if="showFooter" #footer>
|
||||
<div class="flex flex-col gap-3">
|
||||
<SettingsInlineWarning v-if="showLockWarning && lockWarningMessage">
|
||||
<IntlFormatted :message-id="lockWarningMessage">
|
||||
<template #contact-support-link="{ children }">
|
||||
<a
|
||||
class="smart-clickable:allow-pointer-events text-orange underline hover:brightness-110"
|
||||
href="https://support.modrinth.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<component :is="() => normalizeChildren(children)" />
|
||||
</a>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</SettingsInlineWarning>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<DisclosureUpdatedBy
|
||||
v-if="updatedAt"
|
||||
:updated-at="updatedAt"
|
||||
:updated-by="updatedBy"
|
||||
:set-by-moderator="setByModerator"
|
||||
/>
|
||||
<span v-else />
|
||||
<ButtonGroup v-if="showModeratorLockControls" class="ml-auto" label="Lock status">
|
||||
<Button
|
||||
v-for="{ status, label } in LOCK_STATUSES"
|
||||
:key="status"
|
||||
:color="
|
||||
status === 'cannot_disable'
|
||||
? 'orange'
|
||||
: status === 'fully_locked'
|
||||
? 'red'
|
||||
: undefined
|
||||
"
|
||||
:type="status !== 'unlocked' ? 'colored-text' : undefined"
|
||||
:disabled="disabled || resolvedLockStatus === status"
|
||||
@click="setLockStatus(status)"
|
||||
>
|
||||
<LockOpenIcon v-if="status === 'unlocked'" />
|
||||
<CircleSlashIcon v-else-if="status === 'cannot_disable'" />
|
||||
<LockIcon v-else />
|
||||
{{ label }}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</SettingsToggleCard>
|
||||
</template>
|
||||
Reference in New Issue
Block a user