You've already forked AstralRinth
forked from didirus/AstralRinth
Fixed permissions issue and modpack issue with environment overhaul
This commit is contained in:
@@ -764,7 +764,16 @@
|
|||||||
>
|
>
|
||||||
{{ formatMessage(messages.environmentMigrationMessage) }}
|
{{ formatMessage(messages.environmentMigrationMessage) }}
|
||||||
<ButtonStyled color="orange">
|
<ButtonStyled color="orange">
|
||||||
<nuxt-link :to="`/project/${project.id}/settings/environment`" class="mt-3 w-fit">
|
<nuxt-link
|
||||||
|
v-tooltip="
|
||||||
|
hasEditDetailsPermission
|
||||||
|
? undefined
|
||||||
|
: formatMessage(commonProjectSettingsMessages.noPermissionDescription)
|
||||||
|
"
|
||||||
|
:to="`/project/${project.id}/settings/environment`"
|
||||||
|
class="mt-3 w-fit"
|
||||||
|
:disabled="!hasEditDetailsPermission"
|
||||||
|
>
|
||||||
<SettingsIcon /> {{ formatMessage(messages.reviewEnvironmentSettings) }}
|
<SettingsIcon /> {{ formatMessage(messages.reviewEnvironmentSettings) }}
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
@@ -957,6 +966,7 @@ import {
|
|||||||
ButtonStyled,
|
ButtonStyled,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
commonMessages,
|
commonMessages,
|
||||||
|
commonProjectSettingsMessages,
|
||||||
injectNotificationManager,
|
injectNotificationManager,
|
||||||
NewModal,
|
NewModal,
|
||||||
OverflowMenu,
|
OverflowMenu,
|
||||||
@@ -1589,6 +1599,11 @@ const currentMember = computed(() => {
|
|||||||
return val
|
return val
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const hasEditDetailsPermission = computed(() => {
|
||||||
|
const EDIT_DETAILS = 1 << 2
|
||||||
|
return (currentMember.value?.permissions & EDIT_DETAILS) === EDIT_DETAILS
|
||||||
|
})
|
||||||
|
|
||||||
versions.value = data.$computeVersions(versions.value, allMembers.value)
|
versions.value = data.$computeVersions(versions.value, allMembers.value)
|
||||||
|
|
||||||
// Q: Why do this instead of computing the versions of featuredVersions?
|
// Q: Why do this instead of computing the versions of featuredVersions?
|
||||||
@@ -1870,6 +1885,7 @@ provideProjectPageContext({
|
|||||||
projectV2: project,
|
projectV2: project,
|
||||||
projectV3,
|
projectV3,
|
||||||
refreshProject: resetProject,
|
refreshProject: resetProject,
|
||||||
|
currentMember,
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { defineMessages, useVIntl } from '@vintl/vintl'
|
|||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
|
|
||||||
const { projectV2, projectV3, refreshProject } = injectProjectPageContext()
|
const { currentMember, projectV2, projectV3, refreshProject } = injectProjectPageContext()
|
||||||
const { handleError } = injectNotificationManager()
|
const { handleError } = injectNotificationManager()
|
||||||
const api = injectApi()
|
const api = injectApi()
|
||||||
|
|
||||||
@@ -32,6 +32,11 @@ const needsToVerify = computed(
|
|||||||
supportsEnvironment.value,
|
supportsEnvironment.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const hasPermission = computed(() => {
|
||||||
|
const EDIT_DETAILS = 1 << 2
|
||||||
|
return (currentMember.value?.permissions & EDIT_DETAILS) === EDIT_DETAILS
|
||||||
|
})
|
||||||
|
|
||||||
function getInitialEnv() {
|
function getInitialEnv() {
|
||||||
return projectV3.value.environment?.length === 1 ? projectV3.value.environment[0] : undefined
|
return projectV3.value.environment?.length === 1 ? projectV3.value.environment[0] : undefined
|
||||||
}
|
}
|
||||||
@@ -106,7 +111,7 @@ const messages = defineMessages({
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<UnsavedChangesPopup
|
<UnsavedChangesPopup
|
||||||
v-if="supportsEnvironment"
|
v-if="supportsEnvironment && hasPermission"
|
||||||
:original="saved"
|
:original="saved"
|
||||||
:modified="current"
|
:modified="current"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
@@ -125,40 +130,43 @@ const messages = defineMessages({
|
|||||||
v-if="!supportsEnvironment"
|
v-if="!supportsEnvironment"
|
||||||
type="critical"
|
type="critical"
|
||||||
:header="formatMessage(messages.wrongProjectTypeTitle)"
|
:header="formatMessage(messages.wrongProjectTypeTitle)"
|
||||||
|
:body="formatMessage(messages.wrongProjectTypeDescription)"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
>
|
/>
|
||||||
{{ formatMessage(messages.wrongProjectTypeDescription) }}
|
|
||||||
</Admonition>
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<Admonition
|
<Admonition
|
||||||
v-if="
|
v-if="!hasPermission"
|
||||||
|
type="critical"
|
||||||
|
:header="formatMessage(commonProjectSettingsMessages.noPermissionTitle)"
|
||||||
|
:body="formatMessage(commonProjectSettingsMessages.noPermissionDescription)"
|
||||||
|
class="mb-3"
|
||||||
|
/>
|
||||||
|
<Admonition
|
||||||
|
v-else-if="
|
||||||
!projectV3.environment ||
|
!projectV3.environment ||
|
||||||
projectV3.environment.length === 0 ||
|
projectV3.environment.length === 0 ||
|
||||||
projectV3.environment[0] === 'unknown'
|
projectV3.environment[0] === 'unknown'
|
||||||
"
|
"
|
||||||
type="critical"
|
type="critical"
|
||||||
:header="formatMessage(messages.missingEnvTitle)"
|
:header="formatMessage(messages.missingEnvTitle)"
|
||||||
|
:body="formatMessage(messages.missingEnvDescription)"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
>
|
/>
|
||||||
{{ formatMessage(messages.missingEnvDescription) }}
|
|
||||||
</Admonition>
|
|
||||||
<Admonition
|
<Admonition
|
||||||
v-else-if="projectV3.environment.length > 1"
|
v-else-if="projectV3.environment.length > 1"
|
||||||
type="info"
|
type="info"
|
||||||
:header="formatMessage(messages.multipleEnvironmentsTitle)"
|
:header="formatMessage(messages.multipleEnvironmentsTitle)"
|
||||||
|
:body="formatMessage(messages.multipleEnvironmentsDescription)"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
>
|
/>
|
||||||
{{ formatMessage(messages.multipleEnvironmentsDescription) }}
|
|
||||||
</Admonition>
|
|
||||||
<Admonition
|
<Admonition
|
||||||
v-else-if="needsToVerify"
|
v-else-if="needsToVerify"
|
||||||
type="warning"
|
type="warning"
|
||||||
:header="formatMessage(messages.reviewOptionsTitle)"
|
:header="formatMessage(messages.reviewOptionsTitle)"
|
||||||
|
:body="formatMessage(messages.reviewOptionsDescription)"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
>
|
/>
|
||||||
{{ formatMessage(messages.reviewOptionsDescription) }}
|
<ProjectSettingsEnvSelector v-model="current.environment" :disabled="!hasPermission" />
|
||||||
</Admonition>
|
|
||||||
<ProjectSettingsEnvSelector v-model="current.environment" />
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -456,9 +456,8 @@ if (user.value?.projects) {
|
|||||||
projects.value = updateSort(user.value.projects, 'Name', false)
|
projects.value = updateSort(user.value.projects, 'Name', false)
|
||||||
user.value?.projectsV3?.forEach((project) => {
|
user.value?.projectsV3?.forEach((project) => {
|
||||||
if (
|
if (
|
||||||
(project.side_types_migration_review_status === 'pending' &&
|
project.side_types_migration_review_status === 'pending' &&
|
||||||
project.project_types.includes('mod')) ||
|
(project.project_types.includes('mod') || project.project_types.includes('modpack'))
|
||||||
project.project_types.includes('modpack')
|
|
||||||
) {
|
) {
|
||||||
projectsWithMigrationWarning.value.push(project.id)
|
projectsWithMigrationWarning.value.push(project.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
class="px-4 py-3 text-left border-0 font-medium border-2 border-button-bg border-solid flex gap-2 transition-all cursor-pointer active:scale-[0.98] hover:bg-button-bg hover:brightness-[--hover-brightness] rounded-xl"
|
class="px-4 py-3 text-left border-0 font-medium border-2 border-button-bg border-solid flex gap-2 transition-all cursor-pointer rounded-xl"
|
||||||
:class="selected ? 'text-contrast bg-button-bg' : 'text-primary bg-transparent'"
|
:class="
|
||||||
|
(selected ? 'text-contrast bg-button-bg' : 'text-primary bg-transparent') +
|
||||||
|
(disabled
|
||||||
|
? ' opacity-50'
|
||||||
|
: ' active:scale-[0.98] hover:bg-button-bg hover:brightness-[--hover-brightness]')
|
||||||
|
"
|
||||||
|
:disabled="disabled"
|
||||||
@click="emit('select')"
|
@click="emit('select')"
|
||||||
>
|
>
|
||||||
<RadioButtonCheckedIcon v-if="selected" class="text-brand h-5 w-5 shrink-0" />
|
<RadioButtonCheckedIcon v-if="selected" class="text-brand h-5 w-5 shrink-0" />
|
||||||
@@ -16,7 +22,13 @@ const emit = defineEmits<{
|
|||||||
(e: 'select'): void
|
(e: 'select'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineProps<{
|
withDefaults(
|
||||||
selected: boolean
|
defineProps<{
|
||||||
}>()
|
selected: boolean
|
||||||
|
disabled?: boolean
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ const { formatMessage } = useVIntl()
|
|||||||
|
|
||||||
const value = defineModel<EnvironmentV3 | undefined>({ required: true })
|
const value = defineModel<EnvironmentV3 | undefined>({ required: true })
|
||||||
|
|
||||||
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
disabled?: boolean
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
type EnvironmentRadioOption = {
|
type EnvironmentRadioOption = {
|
||||||
title: MessageDescriptor
|
title: MessageDescriptor
|
||||||
description?: MessageDescriptor
|
description?: MessageDescriptor
|
||||||
@@ -224,6 +233,7 @@ const simulateSave = ref(false)
|
|||||||
class="!w-full"
|
class="!w-full"
|
||||||
:class="{ 'mt-2': index > 0 }"
|
:class="{ 'mt-2': index > 0 }"
|
||||||
:selected="currentOuterOption === key"
|
:selected="currentOuterOption === key"
|
||||||
|
:disabled="disabled"
|
||||||
@select="
|
@select="
|
||||||
() => {
|
() => {
|
||||||
if (currentOuterOption !== key) {
|
if (currentOuterOption !== key) {
|
||||||
@@ -252,6 +262,7 @@ const simulateSave = ref(false)
|
|||||||
'opacity-50': currentOuterOption !== key,
|
'opacity-50': currentOuterOption !== key,
|
||||||
}"
|
}"
|
||||||
:selected="currentSubOption === suboptionKey"
|
:selected="currentSubOption === suboptionKey"
|
||||||
|
:disabled="disabled"
|
||||||
@select="
|
@select="
|
||||||
() => {
|
() => {
|
||||||
currentOuterOption = key
|
currentOuterOption = key
|
||||||
|
|||||||
@@ -506,6 +506,12 @@
|
|||||||
"project.settings.members.title": {
|
"project.settings.members.title": {
|
||||||
"defaultMessage": "Members"
|
"defaultMessage": "Members"
|
||||||
},
|
},
|
||||||
|
"project.settings.notice.no-permission.description": {
|
||||||
|
"defaultMessage": "You don't have permission to edit this."
|
||||||
|
},
|
||||||
|
"project.settings.notice.no-permission.title": {
|
||||||
|
"defaultMessage": "No permission"
|
||||||
|
},
|
||||||
"project.settings.tags.title": {
|
"project.settings.tags.title": {
|
||||||
"defaultMessage": "Tags"
|
"defaultMessage": "Tags"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Project, ProjectV3Partial } from '@modrinth/utils'
|
import type { Project, ProjectV3Partial, TeamMember } from '@modrinth/utils'
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
import { createContext } from '.'
|
import { createContext } from '.'
|
||||||
@@ -7,6 +7,7 @@ export interface ProjectPageContext {
|
|||||||
projectV2: Ref<Project>
|
projectV2: Ref<Project>
|
||||||
projectV3: Ref<ProjectV3Partial>
|
projectV3: Ref<ProjectV3Partial>
|
||||||
refreshProject: () => Promise<void>
|
refreshProject: () => Promise<void>
|
||||||
|
currentMember: Ref<TeamMember>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const [injectProjectPageContext, provideProjectPageContext] =
|
export const [injectProjectPageContext, provideProjectPageContext] =
|
||||||
|
|||||||
@@ -331,6 +331,14 @@ export const commonProjectSettingsMessages = defineMessages({
|
|||||||
id: 'project.settings.members.title',
|
id: 'project.settings.members.title',
|
||||||
defaultMessage: 'Members',
|
defaultMessage: 'Members',
|
||||||
},
|
},
|
||||||
|
noPermissionDescription: {
|
||||||
|
id: 'project.settings.notice.no-permission.description',
|
||||||
|
defaultMessage: `You don't have permission to edit this.`,
|
||||||
|
},
|
||||||
|
noPermissionTitle: {
|
||||||
|
id: 'project.settings.notice.no-permission.title',
|
||||||
|
defaultMessage: 'No permission',
|
||||||
|
},
|
||||||
tags: {
|
tags: {
|
||||||
id: 'project.settings.tags.title',
|
id: 'project.settings.tags.title',
|
||||||
defaultMessage: 'Tags',
|
defaultMessage: 'Tags',
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ export type VersionEntry = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const VERSIONS: VersionEntry[] = [
|
const VERSIONS: VersionEntry[] = [
|
||||||
|
{
|
||||||
|
date: `2025-08-28T18:45:00-07:00`,
|
||||||
|
product: 'web',
|
||||||
|
body: `### Improvements
|
||||||
|
- Fixed modpacks showing an environment migration warning perpetually.
|
||||||
|
- Fixed environment settings being unclear about permissions.`,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
date: `2025-08-28T16:50:00-07:00`,
|
date: `2025-08-28T16:50:00-07:00`,
|
||||||
product: 'web',
|
product: 'web',
|
||||||
|
|||||||
Reference in New Issue
Block a user