mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 03:55:59 +00:00
feat: smaller qa points
This commit is contained in:
@@ -15,12 +15,12 @@
|
|||||||
</PageHeaderBadgeItem>
|
</PageHeaderBadgeItem>
|
||||||
<PageHeaderBadgeItem
|
<PageHeaderBadgeItem
|
||||||
v-else
|
v-else
|
||||||
:icon="UnknownIcon"
|
|
||||||
:tooltip="sharedInstanceTooltip"
|
:tooltip="sharedInstanceTooltip"
|
||||||
aria-label="Shared instance information"
|
aria-label="Shared instance information"
|
||||||
class="!border-blue !bg-highlight-blue !text-blue"
|
class="!border-blue !bg-highlight-blue !text-blue"
|
||||||
>
|
>
|
||||||
Shared
|
Shared
|
||||||
|
<UnknownIcon class="block size-4 shrink-0 text-current" aria-hidden="true" />
|
||||||
</PageHeaderBadgeItem>
|
</PageHeaderBadgeItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<template #cell-id="{ row }">
|
<template #cell-id="{ row }">
|
||||||
<CopyCode
|
<CopyCode
|
||||||
:text="`${config.siteUrl}/share/${encodeURIComponent(row.id)}`"
|
:text="`${config.siteUrl}/share/${encodeURIComponent(row.id)}`"
|
||||||
:display-text="row.id"
|
:display-text="`/${row.id}`"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #cell-uses="{ row }">
|
<template #cell-uses="{ row }">
|
||||||
@@ -172,11 +172,11 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
activeInvitesDescription: {
|
activeInvitesDescription: {
|
||||||
id: 'instance.settings.sharing.active-invites.description',
|
id: 'instance.settings.sharing.active-invites.description',
|
||||||
defaultMessage: 'Anyone with one of these invite codes can join while it remains active.',
|
defaultMessage: 'Anyone with one of these invite links can join while it remains active.',
|
||||||
},
|
},
|
||||||
inviteCodeLabel: {
|
inviteCodeLabel: {
|
||||||
id: 'instance.settings.sharing.active-invites.code',
|
id: 'instance.settings.sharing.active-invites.code',
|
||||||
defaultMessage: 'Invite code',
|
defaultMessage: 'Invite link',
|
||||||
},
|
},
|
||||||
usesLabel: {
|
usesLabel: {
|
||||||
id: 'instance.settings.sharing.active-invites.uses',
|
id: 'instance.settings.sharing.active-invites.uses',
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ const messages = defineMessages({
|
|||||||
admonitionBody: {
|
admonitionBody: {
|
||||||
id: 'instance.settings.sharing.revoke-invite.admonition-body',
|
id: 'instance.settings.sharing.revoke-invite.admonition-body',
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
'The invite code <monospace>{code}</monospace> will stop working immediately. People who already joined will keep access.',
|
'The invite link <monospace>{code}</monospace> will stop working immediately. People who already joined will keep access.',
|
||||||
},
|
},
|
||||||
revokeButton: {
|
revokeButton: {
|
||||||
id: 'instance.settings.sharing.revoke-invite.confirm',
|
id: 'instance.settings.sharing.revoke-invite.confirm',
|
||||||
|
|||||||
+3
-5
@@ -70,10 +70,7 @@
|
|||||||
:values="{ username: creator.username }"
|
:values="{ username: creator.username }"
|
||||||
>
|
>
|
||||||
<template #creator="{ children }">
|
<template #creator="{ children }">
|
||||||
<AutoLink
|
<AutoLink :to="creatorProfileLink" class="font-medium text-contrast hover:underline">
|
||||||
:to="creatorProfileLink"
|
|
||||||
class="inline-flex items-center gap-1 align-middle font-medium text-contrast hover:underline"
|
|
||||||
>
|
|
||||||
<Avatar
|
<Avatar
|
||||||
:src="creator.avatarUrl"
|
:src="creator.avatarUrl"
|
||||||
:alt="creator.username"
|
:alt="creator.username"
|
||||||
@@ -81,8 +78,9 @@
|
|||||||
size="24px"
|
size="24px"
|
||||||
circle
|
circle
|
||||||
no-shadow
|
no-shadow
|
||||||
|
class="mr-1 inline-block align-middle"
|
||||||
/>
|
/>
|
||||||
<component :is="() => children" />
|
<span><component :is="() => children" /></span>
|
||||||
</AutoLink>
|
</AutoLink>
|
||||||
</template>
|
</template>
|
||||||
</IntlFormatted>
|
</IntlFormatted>
|
||||||
|
|||||||
+13
-2
@@ -1,7 +1,7 @@
|
|||||||
import type { Labrinth } from '@modrinth/api-client'
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
import type { ContentItem } from '@modrinth/ui'
|
import type { ContentItem } from '@modrinth/ui'
|
||||||
|
|
||||||
import { get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
import { get_project, get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
||||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||||
|
|
||||||
type VersionDependency = Labrinth.Versions.v2.Dependency & { version_id?: string }
|
type VersionDependency = Labrinth.Versions.v2.Dependency & { version_id?: string }
|
||||||
@@ -20,7 +20,18 @@ export function useSharedInstancePreviewContent() {
|
|||||||
async function modpackContentItems(preview: SharedInstanceInstallPreview) {
|
async function modpackContentItems(preview: SharedInstanceInstallPreview) {
|
||||||
if (!preview.modpackVersionId) return []
|
if (!preview.modpackVersionId) return []
|
||||||
const version = await get_version(preview.modpackVersionId, 'must_revalidate')
|
const version = await get_version(preview.modpackVersionId, 'must_revalidate')
|
||||||
return await contentItemsFromDependencies(version?.dependencies ?? [])
|
if (!version) return []
|
||||||
|
|
||||||
|
const [project, contentItems] = await Promise.all([
|
||||||
|
get_project(version.project_id, 'must_revalidate'),
|
||||||
|
contentItemsFromDependencies(version.dependencies ?? []),
|
||||||
|
])
|
||||||
|
if (!project) return contentItems
|
||||||
|
|
||||||
|
return contentItems.map((item) => ({
|
||||||
|
...item,
|
||||||
|
source: { project },
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function contentItemsFromDependencies(dependencies: Labrinth.Versions.v2.Dependency[]) {
|
async function contentItemsFromDependencies(dependencies: Labrinth.Versions.v2.Dependency[]) {
|
||||||
|
|||||||
@@ -623,6 +623,9 @@
|
|||||||
"app.modal.install-to-play.invite-warning": {
|
"app.modal.install-to-play.invite-warning": {
|
||||||
"message": "This invite was created by another Modrinth user, not Modrinth. Only accept invites from people you trust."
|
"message": "This invite was created by another Modrinth user, not Modrinth. Only accept invites from people you trust."
|
||||||
},
|
},
|
||||||
|
"app.modal.install-to-play.invite-warning-with-creator": {
|
||||||
|
"message": "This invite was created by <creator>{username}</creator>, not Modrinth. Only accept invites from people you trust."
|
||||||
|
},
|
||||||
"app.modal.install-to-play.mod-count": {
|
"app.modal.install-to-play.mod-count": {
|
||||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||||
},
|
},
|
||||||
@@ -1194,10 +1197,10 @@
|
|||||||
"message": "Actions"
|
"message": "Actions"
|
||||||
},
|
},
|
||||||
"instance.settings.sharing.active-invites.code": {
|
"instance.settings.sharing.active-invites.code": {
|
||||||
"message": "Invite code"
|
"message": "Invite link"
|
||||||
},
|
},
|
||||||
"instance.settings.sharing.active-invites.description": {
|
"instance.settings.sharing.active-invites.description": {
|
||||||
"message": "Anyone with one of these invite codes can join while it remains active."
|
"message": "Anyone with one of these invite links can join while it remains active."
|
||||||
},
|
},
|
||||||
"instance.settings.sharing.active-invites.empty": {
|
"instance.settings.sharing.active-invites.empty": {
|
||||||
"message": "There are no active invites."
|
"message": "There are no active invites."
|
||||||
@@ -1218,7 +1221,7 @@
|
|||||||
"message": "Uses"
|
"message": "Uses"
|
||||||
},
|
},
|
||||||
"instance.settings.sharing.revoke-invite.admonition-body": {
|
"instance.settings.sharing.revoke-invite.admonition-body": {
|
||||||
"message": "The invite code <monospace>{code}</monospace> will stop working immediately. People who already joined will keep access."
|
"message": "The invite link <monospace>{code}</monospace> will stop working immediately. People who already joined will keep access."
|
||||||
},
|
},
|
||||||
"instance.settings.sharing.revoke-invite.admonition-header": {
|
"instance.settings.sharing.revoke-invite.admonition-header": {
|
||||||
"message": "This action cannot be undone"
|
"message": "This action cannot be undone"
|
||||||
|
|||||||
@@ -604,13 +604,18 @@ async function loadSharedInstanceVersionContent(
|
|||||||
dependency.project_id ? [dependency.project_id] : [],
|
dependency.project_id ? [dependency.project_id] : [],
|
||||||
)
|
)
|
||||||
const projectIds = [
|
const projectIds = [
|
||||||
...new Set([...versions.map((version) => version.project_id), ...dependencyProjectIds]),
|
...new Set([
|
||||||
|
...versions.map((version) => version.project_id),
|
||||||
|
...dependencyProjectIds,
|
||||||
|
...(modpackVersion ? [modpackVersion.project_id] : []),
|
||||||
|
]),
|
||||||
]
|
]
|
||||||
const projects = projectIds.length
|
const projects = projectIds.length
|
||||||
? await client.labrinth.projects_v2.getMultiple(projectIds)
|
? await client.labrinth.projects_v2.getMultiple(projectIds)
|
||||||
: []
|
: []
|
||||||
const versionsById = new Map(versions.map((version) => [version.id, version]))
|
const versionsById = new Map(versions.map((version) => [version.id, version]))
|
||||||
const projectsById = new Map(projects.map((project) => [project.id, project]))
|
const projectsById = new Map(projects.map((project) => [project.id, project]))
|
||||||
|
const modpackProject = modpackVersion ? projectsById.get(modpackVersion.project_id) : undefined
|
||||||
|
|
||||||
const directContent: ContentItem[] = [...new Set(directVersionIds)].flatMap((versionId) => {
|
const directContent: ContentItem[] = [...new Set(directVersionIds)].flatMap((versionId) => {
|
||||||
const version = versionsById.get(versionId)
|
const version = versionsById.get(versionId)
|
||||||
@@ -633,13 +638,19 @@ async function loadSharedInstanceVersionContent(
|
|||||||
const fileName =
|
const fileName =
|
||||||
primaryFile?.filename ?? dependency.file_name ?? project?.title ?? version?.name ?? 'Unknown'
|
primaryFile?.filename ?? dependency.file_name ?? project?.title ?? version?.name ?? 'Unknown'
|
||||||
|
|
||||||
return sharedInstanceContentItem(
|
const item = sharedInstanceContentItem(
|
||||||
version,
|
version,
|
||||||
project,
|
project,
|
||||||
fileName,
|
fileName,
|
||||||
dependency.project_id ?? fileName,
|
dependency.project_id ?? fileName,
|
||||||
!project && !version,
|
!project && !version,
|
||||||
)
|
)
|
||||||
|
return modpackProject
|
||||||
|
? {
|
||||||
|
...item,
|
||||||
|
source: { project: modpackProject },
|
||||||
|
}
|
||||||
|
: item
|
||||||
})
|
})
|
||||||
|
|
||||||
const externalContent: ContentItem[] = instanceVersion.external_files.map((file, index) => ({
|
const externalContent: ContentItem[] = instanceVersion.external_files.map((file, index) => ({
|
||||||
|
|||||||
@@ -224,12 +224,11 @@ fn normalize_svg_from_path(icon_path: &Path) -> crate::Result<Bytes> {
|
|||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
if metadata.len() > INSTANCE_ICON_MAX_SVG_SOURCE_BYTES {
|
if metadata.len() > INSTANCE_ICON_MAX_SVG_SOURCE_BYTES {
|
||||||
return Err(crate::ErrorKind::InputError(format!(
|
return Err(crate::ErrorKind::InputError(format!(
|
||||||
"SVG instance icons cannot exceed {} bytes before normalization",
|
"SVG instance icons cannot exceed {INSTANCE_ICON_MAX_SVG_SOURCE_BYTES} bytes before normalization"
|
||||||
INSTANCE_ICON_MAX_SVG_SOURCE_BYTES
|
))
|
||||||
))
|
.into());
|
||||||
.into());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let bytes = std::fs::read(icon_path).map_err(|error| {
|
let bytes = std::fs::read(icon_path).map_err(|error| {
|
||||||
crate::ErrorKind::InputError(format!(
|
crate::ErrorKind::InputError(format!(
|
||||||
@@ -245,15 +244,16 @@ fn normalize_svg(
|
|||||||
resources_dir: Option<&Path>,
|
resources_dir: Option<&Path>,
|
||||||
) -> crate::Result<Bytes> {
|
) -> crate::Result<Bytes> {
|
||||||
if bytes.len() as u64 > INSTANCE_ICON_MAX_SVG_SOURCE_BYTES {
|
if bytes.len() as u64 > INSTANCE_ICON_MAX_SVG_SOURCE_BYTES {
|
||||||
return Err(crate::ErrorKind::InputError(format!(
|
return Err(crate::ErrorKind::InputError(format!(
|
||||||
"SVG instance icons cannot exceed {} bytes before normalization",
|
"SVG instance icons cannot exceed {INSTANCE_ICON_MAX_SVG_SOURCE_BYTES} bytes before normalization"
|
||||||
INSTANCE_ICON_MAX_SVG_SOURCE_BYTES
|
))
|
||||||
))
|
.into());
|
||||||
.into());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut options = resvg::usvg::Options::default();
|
let mut options = resvg::usvg::Options {
|
||||||
options.resources_dir = resources_dir.map(Path::to_path_buf);
|
resources_dir: resources_dir.map(Path::to_path_buf),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
options.fontdb_mut().load_system_fonts();
|
options.fontdb_mut().load_system_fonts();
|
||||||
let tree =
|
let tree =
|
||||||
resvg::usvg::Tree::from_data(bytes, &options).map_err(|error| {
|
resvg::usvg::Tree::from_data(bytes, &options).map_err(|error| {
|
||||||
@@ -308,9 +308,8 @@ fn has_svg_extension(path: &Path) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn icon_too_large_error() -> crate::Error {
|
fn icon_too_large_error() -> crate::Error {
|
||||||
crate::ErrorKind::InputError(format!(
|
crate::ErrorKind::InputError(format!(
|
||||||
"Instance icons cannot exceed {} bytes",
|
"Instance icons cannot exceed {INSTANCE_ICON_MAX_BYTES} bytes"
|
||||||
INSTANCE_ICON_MAX_BYTES
|
))
|
||||||
))
|
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import type {
|
|||||||
ContentCardProject,
|
ContentCardProject,
|
||||||
ContentCardVersion,
|
ContentCardVersion,
|
||||||
ContentOwner,
|
ContentOwner,
|
||||||
|
ContentSource,
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
@@ -46,6 +47,7 @@ interface Props {
|
|||||||
version?: ContentCardVersion
|
version?: ContentCardVersion
|
||||||
versionLink?: string | RouteLocationRaw
|
versionLink?: string | RouteLocationRaw
|
||||||
owner?: ContentOwner
|
owner?: ContentOwner
|
||||||
|
source?: ContentSource
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
installing?: boolean
|
installing?: boolean
|
||||||
hasUpdate?: boolean
|
hasUpdate?: boolean
|
||||||
@@ -68,6 +70,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
version: undefined,
|
version: undefined,
|
||||||
versionLink: undefined,
|
versionLink: undefined,
|
||||||
owner: undefined,
|
owner: undefined,
|
||||||
|
source: undefined,
|
||||||
enabled: undefined,
|
enabled: undefined,
|
||||||
installing: false,
|
installing: false,
|
||||||
hasUpdate: false,
|
hasUpdate: false,
|
||||||
@@ -196,8 +199,32 @@ const deleteHovered = ref(false)
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex min-w-0 items-center gap-1">
|
<div class="flex min-w-0 items-center gap-1">
|
||||||
|
<template v-if="source">
|
||||||
|
<AutoLink
|
||||||
|
:target="
|
||||||
|
typeof source.link === 'string' && source.link.startsWith('http')
|
||||||
|
? '_blank'
|
||||||
|
: undefined
|
||||||
|
"
|
||||||
|
:to="source.link"
|
||||||
|
class="flex min-w-0 items-center gap-1 !decoration-secondary"
|
||||||
|
:class="{ 'hover:underline': source.link }"
|
||||||
|
>
|
||||||
|
<Avatar
|
||||||
|
:src="source.project.icon_url"
|
||||||
|
:alt="source.project.title"
|
||||||
|
:tint-by="source.project.id"
|
||||||
|
size="1.25rem"
|
||||||
|
no-shadow
|
||||||
|
class="shrink-0 rounded-md"
|
||||||
|
/>
|
||||||
|
<span class="truncate text-sm leading-5 text-secondary">
|
||||||
|
{{ source.project.title }}
|
||||||
|
</span>
|
||||||
|
</AutoLink>
|
||||||
|
</template>
|
||||||
<AutoLink
|
<AutoLink
|
||||||
v-if="owner"
|
v-else-if="owner"
|
||||||
:target="
|
:target="
|
||||||
typeof owner.link === 'string' && owner.link.startsWith('http')
|
typeof owner.link === 'string' && owner.link.startsWith('http')
|
||||||
? '_blank'
|
? '_blank'
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ function handleSort(column: ContentCardTableSortColumn) {
|
|||||||
:version="item.version"
|
:version="item.version"
|
||||||
:version-link="item.versionLink"
|
:version-link="item.versionLink"
|
||||||
:owner="item.owner"
|
:owner="item.owner"
|
||||||
|
:source="item.source"
|
||||||
:enabled="item.enabled"
|
:enabled="item.enabled"
|
||||||
:installing="item.installing"
|
:installing="item.installing"
|
||||||
:has-update="item.hasUpdate"
|
:has-update="item.hasUpdate"
|
||||||
@@ -327,6 +328,7 @@ function handleSort(column: ContentCardTableSortColumn) {
|
|||||||
:version="item.version"
|
:version="item.version"
|
||||||
:version-link="item.versionLink"
|
:version-link="item.versionLink"
|
||||||
:owner="item.owner"
|
:owner="item.owner"
|
||||||
|
:source="item.source"
|
||||||
:enabled="item.enabled"
|
:enabled="item.enabled"
|
||||||
:installing="item.installing"
|
:installing="item.installing"
|
||||||
:has-update="item.hasUpdate"
|
:has-update="item.hasUpdate"
|
||||||
|
|||||||
+16
-2
@@ -20,6 +20,7 @@ import type { Option as OverflowMenuOption } from '#ui/components/base/OverflowM
|
|||||||
import StyledInput from '#ui/components/base/StyledInput.vue'
|
import StyledInput from '#ui/components/base/StyledInput.vue'
|
||||||
import NewModal from '#ui/components/modal/NewModal.vue'
|
import NewModal from '#ui/components/modal/NewModal.vue'
|
||||||
import { defineMessages, useVIntl } from '#ui/composables/i18n'
|
import { defineMessages, useVIntl } from '#ui/composables/i18n'
|
||||||
|
import { injectPageContext } from '#ui/providers/page-context'
|
||||||
import {
|
import {
|
||||||
commonMessages,
|
commonMessages,
|
||||||
commonProjectTypeCategoryMessages,
|
commonProjectTypeCategoryMessages,
|
||||||
@@ -28,11 +29,12 @@ import {
|
|||||||
} from '#ui/utils/common-messages'
|
} from '#ui/utils/common-messages'
|
||||||
|
|
||||||
import { getClientWarningType, isClientOnlyEnvironment } from '../../composables/content-filtering'
|
import { getClientWarningType, isClientOnlyEnvironment } from '../../composables/content-filtering'
|
||||||
import type { ContentCardTableItem, ContentItem } from '../../types'
|
import type { ContentCardProject, ContentCardTableItem, ContentItem } from '../../types'
|
||||||
import ContentCardTable from '../ContentCardTable.vue'
|
import ContentCardTable from '../ContentCardTable.vue'
|
||||||
import ContentSelectionBar from '../ContentSelectionBar.vue'
|
import ContentSelectionBar from '../ContentSelectionBar.vue'
|
||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
|
const pageContext = injectPageContext(null)
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
header?: string
|
header?: string
|
||||||
@@ -263,6 +265,12 @@ const tableItems = computed<ContentCardTableItem[]>(() =>
|
|||||||
link: `https://modrinth.com/${item.owner.type}/${item.owner.id}`,
|
link: `https://modrinth.com/${item.owner.type}/${item.owner.id}`,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
|
source: item.source
|
||||||
|
? {
|
||||||
|
...item.source,
|
||||||
|
link: item.source.link ?? sourceProjectLink(item.source.project),
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
...(props.enableToggle ? { enabled: item.enabled } : {}),
|
...(props.enableToggle ? { enabled: item.enabled } : {}),
|
||||||
installing: item.installing === true,
|
installing: item.installing === true,
|
||||||
toggleDisabled: props.actionDisabled,
|
toggleDisabled: props.actionDisabled,
|
||||||
@@ -290,7 +298,7 @@ const tableItems = computed<ContentCardTableItem[]>(() =>
|
|||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
const externalItemIds = computed(
|
const externalItemIds = computed(
|
||||||
() => new Set(items.value.filter((item) => item.external).map((item) => item.id)),
|
() => new Set(items.value.filter((item) => item.external && !item.source).map((item) => item.id)),
|
||||||
)
|
)
|
||||||
const externalSlicerUrls = computed(() => {
|
const externalSlicerUrls = computed(() => {
|
||||||
const urls: Record<string, string> = {}
|
const urls: Record<string, string> = {}
|
||||||
@@ -332,6 +340,12 @@ function itemDisplayName(item: ContentItem) {
|
|||||||
return item.project?.title ?? item.file_name
|
return item.project?.title ?? item.file_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sourceProjectLink(project: ContentCardProject) {
|
||||||
|
const projectId = project.slug ?? project.id
|
||||||
|
const url = `https://modrinth.com/modpack/${encodeURIComponent(projectId)}`
|
||||||
|
return pageContext ? () => pageContext.openExternalUrl(url) : url
|
||||||
|
}
|
||||||
|
|
||||||
function handleEnabledChange(id: string, value: boolean) {
|
function handleEnabledChange(id: string, value: boolean) {
|
||||||
if (props.actionDisabled) return
|
if (props.actionDisabled) return
|
||||||
const item = items.value.find((item) => item.id === id)
|
const item = items.value.find((item) => item.id === id)
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ export interface ContentOwner {
|
|||||||
link?: string | RouteLocationRaw | (() => void)
|
link?: string | RouteLocationRaw | (() => void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ContentSource {
|
||||||
|
project: ContentCardProject
|
||||||
|
link?: string | RouteLocationRaw | (() => void)
|
||||||
|
}
|
||||||
|
|
||||||
export type ClientWarningType = 'retained' | 'depends' | 'environment'
|
export type ClientWarningType = 'retained' | 'depends' | 'environment'
|
||||||
|
|
||||||
export type ContentSourceKind =
|
export type ContentSourceKind =
|
||||||
@@ -44,6 +49,7 @@ export interface ContentCardTableItem {
|
|||||||
version?: ContentCardVersion
|
version?: ContentCardVersion
|
||||||
versionLink?: string | RouteLocationRaw
|
versionLink?: string | RouteLocationRaw
|
||||||
owner?: ContentOwner
|
owner?: ContentOwner
|
||||||
|
source?: ContentSource
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
disabledTooltip?: string | null
|
disabledTooltip?: string | null
|
||||||
|
|||||||
Reference in New Issue
Block a user