External projects moderator database (#5692)
* Begin external projects moderator database frontend * add copy link button * begin project page permissions settings * MEL database backend routes * include filename in external files * Hook up frontend external license page to backend * more work on user-facing external projects stuff * put user-facing stuff behind feature flag * prepr * clippy --------- Co-authored-by: aecsocket <aecsocket@tutanota.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import { LabrinthAuthInternalModule } from './labrinth/auth/internal'
|
||||
import { LabrinthAuthV2Module } from './labrinth/auth/v2'
|
||||
import { LabrinthBillingInternalModule } from './labrinth/billing/internal'
|
||||
import { LabrinthCollectionsModule } from './labrinth/collections'
|
||||
import { LabrinthExternalProjectsInternalModule } from './labrinth/external-projects/internal'
|
||||
import { LabrinthGlobalsInternalModule } from './labrinth/globals/internal'
|
||||
import { LabrinthLimitsV3Module } from './labrinth/limits/v3'
|
||||
import { LabrinthModerationInternalModule } from './labrinth/moderation/internal'
|
||||
@@ -75,6 +76,7 @@ export const MODULE_REGISTRY = {
|
||||
labrinth_auth_v2: LabrinthAuthV2Module,
|
||||
labrinth_billing_internal: LabrinthBillingInternalModule,
|
||||
labrinth_collections: LabrinthCollectionsModule,
|
||||
labrinth_external_projects_internal: LabrinthExternalProjectsInternalModule,
|
||||
labrinth_globals_internal: LabrinthGlobalsInternalModule,
|
||||
labrinth_moderation_internal: LabrinthModerationInternalModule,
|
||||
labrinth_notifications_v2: LabrinthNotificationsV2Module,
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { AbstractModule } from '../../../core/abstract-module'
|
||||
import type { Labrinth } from '../types'
|
||||
|
||||
export class LabrinthExternalProjectsInternalModule extends AbstractModule {
|
||||
public getModuleID(): string {
|
||||
return 'labrinth_external_projects_internal'
|
||||
}
|
||||
|
||||
public async search(
|
||||
data: Labrinth.ExternalProjects.Internal.SearchRequest,
|
||||
): Promise<Labrinth.ExternalProjects.Internal.ExternalProject[]> {
|
||||
return this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject[]>(
|
||||
'/moderation/external-license/search',
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'POST',
|
||||
body: data,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
public async getBySha1(
|
||||
sha1: string,
|
||||
): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {
|
||||
return this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(
|
||||
`/moderation/external-license/by-sha1/${sha1}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'GET',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
public async update(
|
||||
id: number,
|
||||
data: Labrinth.ExternalProjects.Internal.UpdateLicenseRequest,
|
||||
): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {
|
||||
return this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(
|
||||
`/moderation/external-license/${id}`,
|
||||
{
|
||||
api: 'labrinth',
|
||||
version: 'internal',
|
||||
method: 'PATCH',
|
||||
body: data,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ export * from './auth/internal'
|
||||
export * from './auth/v2'
|
||||
export * from './billing/internal'
|
||||
export * from './collections'
|
||||
export * from './external-projects/internal'
|
||||
export * from './globals/internal'
|
||||
export * from './limits/v3'
|
||||
export * from './moderation/internal'
|
||||
|
||||
@@ -1462,6 +1462,52 @@ export namespace Labrinth {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ExternalProjects {
|
||||
export namespace Internal {
|
||||
export type ExternalLicenseStatus =
|
||||
| 'yes'
|
||||
| 'with-attribution-and-source'
|
||||
| 'with-attribution'
|
||||
| 'no'
|
||||
| 'permanent-no'
|
||||
| 'unidentified'
|
||||
|
||||
export type LinkedFile = {
|
||||
name: string | null
|
||||
sha1: string
|
||||
}
|
||||
|
||||
export type ExternalProject = {
|
||||
id: number
|
||||
title: string | null
|
||||
status: ExternalLicenseStatus
|
||||
link: string | null
|
||||
exceptions: string | null
|
||||
proof: string | null
|
||||
flame_project_id: number | null
|
||||
inserted_at: string | null
|
||||
inserted_by: number | null
|
||||
updated_at: string | null
|
||||
updated_by: number | null
|
||||
linked_files: LinkedFile[]
|
||||
}
|
||||
|
||||
export type SearchRequest = {
|
||||
title?: string
|
||||
flame_id?: number
|
||||
}
|
||||
|
||||
export type UpdateLicenseRequest = {
|
||||
title?: string
|
||||
status: ExternalLicenseStatus
|
||||
link?: string
|
||||
exceptions?: string
|
||||
proof?: string
|
||||
flame_project_id?: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TechReview {
|
||||
export namespace Internal {
|
||||
export type SearchProjectsRequest = {
|
||||
|
||||
@@ -26,6 +26,7 @@ import _BadgeDollarSignIcon from './icons/badge-dollar-sign.svg?component'
|
||||
import _BanIcon from './icons/ban.svg?component'
|
||||
import _BellIcon from './icons/bell.svg?component'
|
||||
import _BellRingIcon from './icons/bell-ring.svg?component'
|
||||
import _BinaryIcon from './icons/binary.svg?component'
|
||||
import _BlendIcon from './icons/blend.svg?component'
|
||||
import _BlocksIcon from './icons/blocks.svg?component'
|
||||
import _BoldIcon from './icons/bold.svg?component'
|
||||
@@ -211,6 +212,7 @@ import _ShieldIcon from './icons/shield.svg?component'
|
||||
import _ShieldAlertIcon from './icons/shield-alert.svg?component'
|
||||
import _ShieldCheckIcon from './icons/shield-check.svg?component'
|
||||
import _SignalIcon from './icons/signal.svg?component'
|
||||
import _SignatureIcon from './icons/signature.svg?component'
|
||||
import _SkullIcon from './icons/skull.svg?component'
|
||||
import _SlashIcon from './icons/slash.svg?component'
|
||||
import _SortAscIcon from './icons/sort-asc.svg?component'
|
||||
@@ -416,6 +418,7 @@ export const BadgeDollarSignIcon = _BadgeDollarSignIcon
|
||||
export const BanIcon = _BanIcon
|
||||
export const BellIcon = _BellIcon
|
||||
export const BellRingIcon = _BellRingIcon
|
||||
export const BinaryIcon = _BinaryIcon
|
||||
export const BlendIcon = _BlendIcon
|
||||
export const BlocksIcon = _BlocksIcon
|
||||
export const BoldIcon = _BoldIcon
|
||||
@@ -601,6 +604,7 @@ export const ShieldIcon = _ShieldIcon
|
||||
export const ShieldAlertIcon = _ShieldAlertIcon
|
||||
export const ShieldCheckIcon = _ShieldCheckIcon
|
||||
export const SignalIcon = _SignalIcon
|
||||
export const SignatureIcon = _SignatureIcon
|
||||
export const SkullIcon = _SkullIcon
|
||||
export const SlashIcon = _SlashIcon
|
||||
export const SortAscIcon = _SortAscIcon
|
||||
|
||||
20
packages/assets/icons/binary.svg
Normal file
20
packages/assets/icons/binary.svg
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- @license lucide-static v0.562.0 - ISC -->
|
||||
<svg
|
||||
class="lucide lucide-binary"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="14" y="14" width="4" height="6" rx="2" />
|
||||
<rect x="6" y="4" width="4" height="6" rx="2" />
|
||||
<path d="M6 20h4" />
|
||||
<path d="M14 10h4" />
|
||||
<path d="M6 14h2v6" />
|
||||
<path d="M14 4h2v6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 487 B |
16
packages/assets/icons/signature.svg
Normal file
16
packages/assets/icons/signature.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- @license lucide-static v0.562.0 - ISC -->
|
||||
<svg
|
||||
class="lucide lucide-signature"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m21 17-2.156-1.868A.5.5 0 0 0 18 15.5v.5a1 1 0 0 1-1 1h-2a1 1 0 0 1-1-1c0-2.545-3.991-3.97-8.5-4a1 1 0 0 0 0 5c4.153 0 4.745-11.295 5.708-13.5a2.5 2.5 0 1 1 3.31 3.284" />
|
||||
<path d="M3 21h18" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 496 B |
@@ -71,6 +71,9 @@
|
||||
variant === 'outlined'
|
||||
? 'bg-transparent border border-solid border-button-bg rounded-l-xl border-r-0'
|
||||
: 'bg-surface-4 border-none rounded-xl',
|
||||
{
|
||||
'placeholder:text-sm': type === 'search',
|
||||
},
|
||||
]"
|
||||
@input="onInput"
|
||||
@focus="isFocused = true"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { TagItem } from '#ui/components'
|
||||
import { externalProjectLicenseStatusMessages } from '#ui/utils'
|
||||
|
||||
import { useVIntl } from '../../composables/i18n'
|
||||
import type { ExternalLicenseStatus } from './types.ts'
|
||||
|
||||
const props = defineProps<{
|
||||
state: ExternalLicenseStatus
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<TagItem>
|
||||
{{ formatMessage(externalProjectLicenseStatusMessages[props.state]) }}
|
||||
</TagItem>
|
||||
</template>
|
||||
@@ -0,0 +1,117 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ClipboardCopyIcon,
|
||||
CurseForgeIcon,
|
||||
FileIcon,
|
||||
LinkIcon,
|
||||
UnknownIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Menu } from 'floating-vue'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { ButtonStyled, CopyCode } from '#ui/components'
|
||||
|
||||
import ExternalProjectLicenseStateTag from './ExternalProjectLicenseStateTag.vue'
|
||||
import type { ExternalLicenseStatus } from './types.ts'
|
||||
|
||||
const props = defineProps<{
|
||||
title: string | null
|
||||
link: string | null
|
||||
state: ExternalLicenseStatus
|
||||
proof: string | null
|
||||
notes: string | null
|
||||
last_updated?: string
|
||||
last_updated_by?: string
|
||||
cf_id?: number | null
|
||||
files: {
|
||||
sha1: string
|
||||
name: string | null
|
||||
}[]
|
||||
}>()
|
||||
|
||||
const lastEditedText = computed(() =>
|
||||
props.last_updated
|
||||
? `Last edited on ${props.last_updated} by ${props.last_updated_by ?? 'unknown'}`
|
||||
: '',
|
||||
)
|
||||
|
||||
async function copyProjectLink() {
|
||||
if (!props.link) return
|
||||
await navigator.clipboard.writeText(props.link)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-surface-3 p-4 rounded-2xl flex flex-col gap-3">
|
||||
<div class="flex gap-4 justify-between">
|
||||
<div class="flex flex-col gap-2">
|
||||
<span class="text-contrast font-semibold">{{ title }}</span>
|
||||
<div v-if="!!link" class="flex gap-2 items-center">
|
||||
<a
|
||||
class="flex items-center gap-2 font-medium hover:underline focus:underline w-fit text-blue"
|
||||
:href="link"
|
||||
target="_blank"
|
||||
>
|
||||
<template v-if="link?.includes('curseforge.com')">
|
||||
<CurseForgeIcon class="size-5 shrink-0" />
|
||||
CurseForge project
|
||||
</template>
|
||||
<template v-else> <LinkIcon class="size-5 shrink-0" /> Project link </template>
|
||||
</a>
|
||||
<ButtonStyled circular type="transparent" size="small">
|
||||
<button v-tooltip="'Copy link'" @click="copyProjectLink">
|
||||
<ClipboardCopyIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-2">
|
||||
<div class="font-medium">Allowed:</div>
|
||||
<div>
|
||||
<ExternalProjectLicenseStateTag :state="state" />
|
||||
</div>
|
||||
<div class="font-medium">Proof:</div>
|
||||
<div>{{ proof ?? 'N/A' }}</div>
|
||||
<template v-if="cf_id">
|
||||
<div class="font-medium">CurseForge ID:</div>
|
||||
<CopyCode :text="`${cf_id}`" />
|
||||
</template>
|
||||
<div class="font-medium">Notes:</div>
|
||||
<div>{{ notes ?? 'N/A' }}</div>
|
||||
</div>
|
||||
<div class="bg-surface-2 p-4 rounded-2xl flex flex-col gap-3">
|
||||
<span class="text-contrast font-semibold">Files</span>
|
||||
<span v-if="!(files?.length > 0)" class="text-secondary">
|
||||
No files available for external project.
|
||||
</span>
|
||||
<div v-else class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-2">
|
||||
<Menu v-for="file in files" :key="file.sha1" :delay="{ hide: 50, show: 0 }">
|
||||
<div
|
||||
class="line-clamp-1 truncate px-2 py-1 flex gap-2 rounded-xl items-center border-solid border-2 border-surface-5 text-sm font-medium text-secondary"
|
||||
>
|
||||
<FileIcon class="shrink-0 size-4" /> {{ file.name ?? file.sha1 }}
|
||||
</div>
|
||||
<template #popper>
|
||||
<div class="text-primary p-2 grid grid-cols-[auto_1fr] gap-x-4 gap-y-2">
|
||||
<div>First identified name:</div>
|
||||
<div v-if="file.name" class="text-sm">
|
||||
{{ file.name }}
|
||||
</div>
|
||||
<div v-else class="text-secondary flex items-center gap-2 text-sm">
|
||||
<UnknownIcon /> Unknown
|
||||
</div>
|
||||
<div>SHA-1:</div>
|
||||
<div class="text-sm"><CopyCode :text="file.sha1" /></div>
|
||||
</div>
|
||||
</template>
|
||||
</Menu>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="last_updated" class="pt-4 border-t-[1px] border-solid border-surface-5">
|
||||
{{ lastEditedText }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,176 @@
|
||||
<script setup lang="ts">
|
||||
import { ChevronDownIcon, ListBulletedIcon, SaveIcon, VersionIcon, XIcon } from '@modrinth/assets'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { Admonition, ButtonStyled, Chips, Collapsible, Combobox, StyledInput } from '#ui/components'
|
||||
|
||||
defineProps<{
|
||||
title: string
|
||||
}>()
|
||||
|
||||
const collapsed = ref(true)
|
||||
|
||||
const selectedPermissionsType = ref('My project')
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
class="bg-surface-2 p-0 rounded-2xl flex flex-col border-[1px] border-solid border-surface-5 overflow-hidden"
|
||||
>
|
||||
<div class="flex items-center bg-surface-3">
|
||||
<button
|
||||
class="flex grow m-0 appearance-none p-4 bg-transparent group transition-all"
|
||||
@click="collapsed = !collapsed"
|
||||
>
|
||||
<span class="flex items-center gap-3 group-active:scale-[0.98]">
|
||||
<ChevronDownIcon
|
||||
class="size-6 text-primary transition-transform duration-300"
|
||||
:class="{ 'rotate-180': !collapsed }"
|
||||
/>
|
||||
<span class="text-contrast font-semibold">{{ title }}</span>
|
||||
</span>
|
||||
</button>
|
||||
<div class="flex items-center gap-2 m-4 ml-0">
|
||||
<ButtonStyled type="outlined">
|
||||
<button>
|
||||
<ListBulletedIcon />
|
||||
Versions
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
<Collapsible
|
||||
:collapsed="collapsed"
|
||||
class="border-0 border-solid border-t border-surface-5 rounded-b-2xl"
|
||||
>
|
||||
<div class="flex flex-col gap-2 p-4">
|
||||
<span class="text-contrast font-semibold">Included in versions:</span>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<template v-for="version in ['4.0.0', '3.5.15', '3.5.14']" :key="version">
|
||||
<div
|
||||
class="px-3 py-2 rounded-xl flex items-center gap-2 border-[1px] border-solid border-surface-5"
|
||||
>
|
||||
<VersionIcon />
|
||||
{{ version }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
class="rounded-2xl p-4 mt-2 border-[1px] border-solid border-surface-5 flex flex-col gap-3"
|
||||
>
|
||||
<span class="text-contrast font-semibold">Type</span>
|
||||
<Chips
|
||||
v-model="selectedPermissionsType"
|
||||
:items="['License', 'My project', 'Special permission', 'No permission']"
|
||||
/>
|
||||
<template v-if="selectedPermissionsType === 'License'">
|
||||
<span>The license of this work permits you to redistribute it in your modpack.</span>
|
||||
<span class="text-contrast font-semibold mt-1">License</span>
|
||||
<Combobox
|
||||
class="max-w-80"
|
||||
:options="[{ label: 'MIT', value: 'MIT' }]"
|
||||
:model-value="'MIT'"
|
||||
/>
|
||||
<span class="text-contrast font-semibold mt-1"> Link to work </span>
|
||||
<StyledInput
|
||||
type="text"
|
||||
class="max-w-[30rem]"
|
||||
placeholder="https://example.com/link-to-work"
|
||||
/>
|
||||
<span class="text-contrast font-semibold mt-1">
|
||||
Notes
|
||||
<span class="font-normal text-primary">(optional)</span>
|
||||
</span>
|
||||
<StyledInput
|
||||
type="text"
|
||||
resize="both"
|
||||
multiline
|
||||
class="max-w-[40rem]"
|
||||
placeholder="Write something here..."
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="selectedPermissionsType === 'My project'">
|
||||
<span>Original work created by you.</span>
|
||||
<span class="text-contrast font-semibold mt-1">License</span>
|
||||
<Combobox
|
||||
class="max-w-80"
|
||||
:options="[{ label: 'MIT', value: 'MIT' }]"
|
||||
:model-value="'MIT'"
|
||||
/>
|
||||
<span class="text-contrast font-semibold mt-1">
|
||||
Notes
|
||||
<span class="font-normal text-primary">(optional)</span>
|
||||
</span>
|
||||
<StyledInput
|
||||
type="text"
|
||||
resize="both"
|
||||
multiline
|
||||
class="max-w-[40rem]"
|
||||
placeholder="Write something here..."
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="selectedPermissionsType === 'Special permission'">
|
||||
<span>
|
||||
You have obtained special permission to redistribute this work in your modpack.
|
||||
</span>
|
||||
<span class="text-contrast font-semibold mt-1"> Link to work </span>
|
||||
<StyledInput
|
||||
type="text"
|
||||
class="max-w-[30rem]"
|
||||
placeholder="https://example.com/link-to-work"
|
||||
/>
|
||||
<div class="flex flex-col gap-1 mt-1">
|
||||
<span class="text-contrast font-semibold"> Proof and explanation </span>
|
||||
<span>
|
||||
Include screenshots of messages, emails, or replies from the copyright owner showing
|
||||
that they granted you permission to redistribute their work in your modpack.
|
||||
</span>
|
||||
</div>
|
||||
<StyledInput
|
||||
type="text"
|
||||
resize="both"
|
||||
multiline
|
||||
class="max-w-[40rem]"
|
||||
placeholder="Write something here..."
|
||||
/>
|
||||
<Admonition
|
||||
type="warning"
|
||||
header="Modrinth staff may attempt to verify submitted proof"
|
||||
>
|
||||
If you are found to have lied or manipulated the images uploaded, your project and
|
||||
account may be terminated.
|
||||
</Admonition>
|
||||
</template>
|
||||
<template v-else-if="selectedPermissionsType === 'No permission'">
|
||||
<span>You don't have permission to use this work.</span>
|
||||
<span class="text-contrast font-semibold mt-1">
|
||||
Notes
|
||||
<span class="font-normal text-primary">(optional)</span>
|
||||
</span>
|
||||
<StyledInput
|
||||
type="text"
|
||||
resize="both"
|
||||
multiline
|
||||
class="max-w-[40rem]"
|
||||
placeholder="Write something here..."
|
||||
/>
|
||||
</template>
|
||||
<hr class="mt-1 bg-surface-5 border-none h-[1px] w-full" />
|
||||
<div class="flex items-center gap-2 justify-end">
|
||||
<ButtonStyled type="outlined">
|
||||
<button>
|
||||
<XIcon />
|
||||
Cancel
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button>
|
||||
<SaveIcon />
|
||||
Save
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Collapsible>
|
||||
</div>
|
||||
</template>
|
||||
3
packages/ui/src/components/external_files/index.ts
Normal file
3
packages/ui/src/components/external_files/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { default as ExternalProjectLicenseStateTag } from './ExternalProjectLicenseStateTag.vue'
|
||||
export { default as ExternalProjectLookupCard } from './ExternalProjectLookupCard.vue'
|
||||
export type { ExternalLicenseStatus } from './types.ts'
|
||||
7
packages/ui/src/components/external_files/types.ts
Normal file
7
packages/ui/src/components/external_files/types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export type ExternalLicenseStatus =
|
||||
| 'yes'
|
||||
| 'with-attribution-and-source'
|
||||
| 'with-attribution'
|
||||
| 'no'
|
||||
| 'permanent-no'
|
||||
| 'unidentified'
|
||||
@@ -5,6 +5,7 @@ export * from './brand'
|
||||
export * from './changelog'
|
||||
export * from './chart'
|
||||
export * from './content'
|
||||
export * from './external_files'
|
||||
export * from './modal'
|
||||
export * from './nav'
|
||||
export * from './page'
|
||||
|
||||
@@ -758,6 +758,24 @@
|
||||
"creation-flow.title.set-up-server": {
|
||||
"defaultMessage": "Set up server"
|
||||
},
|
||||
"external-project-license-status.no": {
|
||||
"defaultMessage": "No"
|
||||
},
|
||||
"external-project-license-status.permanent-no": {
|
||||
"defaultMessage": "Permanent no"
|
||||
},
|
||||
"external-project-license-status.unidentified": {
|
||||
"defaultMessage": "Unidentified"
|
||||
},
|
||||
"external-project-license-status.with-attribution": {
|
||||
"defaultMessage": "With attribution"
|
||||
},
|
||||
"external-project-license-status.with-attribution-and-source": {
|
||||
"defaultMessage": "With attribution and source"
|
||||
},
|
||||
"external-project-license-status.yes": {
|
||||
"defaultMessage": "Yes"
|
||||
},
|
||||
"files.conflict-modal.header": {
|
||||
"defaultMessage": "Extract summary"
|
||||
},
|
||||
@@ -2789,6 +2807,9 @@
|
||||
"project.settings.upload.title": {
|
||||
"defaultMessage": "Upload"
|
||||
},
|
||||
"project.settings.versions.permissions": {
|
||||
"defaultMessage": "Permissions"
|
||||
},
|
||||
"project.settings.versions.title": {
|
||||
"defaultMessage": "Versions"
|
||||
},
|
||||
|
||||
@@ -952,6 +952,10 @@ export const commonProjectSettingsMessages = defineMessages({
|
||||
id: 'project.settings.versions.title',
|
||||
defaultMessage: 'Versions',
|
||||
},
|
||||
permissions: {
|
||||
id: 'project.settings.versions.permissions',
|
||||
defaultMessage: 'Permissions',
|
||||
},
|
||||
view: {
|
||||
id: 'project.settings.view.title',
|
||||
defaultMessage: 'View',
|
||||
@@ -1090,3 +1094,30 @@ export const paymentMethodMessages = defineMessages({
|
||||
defaultMessage: 'Charities',
|
||||
},
|
||||
})
|
||||
|
||||
export const externalProjectLicenseStatusMessages = defineMessages({
|
||||
yes: {
|
||||
id: 'external-project-license-status.yes',
|
||||
defaultMessage: 'Yes',
|
||||
},
|
||||
'with-attribution-and-source': {
|
||||
id: 'external-project-license-status.with-attribution-and-source',
|
||||
defaultMessage: 'With attribution and source',
|
||||
},
|
||||
'with-attribution': {
|
||||
id: 'external-project-license-status.with-attribution',
|
||||
defaultMessage: 'With attribution',
|
||||
},
|
||||
no: {
|
||||
id: 'external-project-license-status.no',
|
||||
defaultMessage: 'No',
|
||||
},
|
||||
'permanent-no': {
|
||||
id: 'external-project-license-status.permanent-no',
|
||||
defaultMessage: 'Permanent no',
|
||||
},
|
||||
unidentified: {
|
||||
id: 'external-project-license-status.unidentified',
|
||||
defaultMessage: 'Unidentified',
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user