Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions app/components/Package/ClaimPackageModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { checkPackageName } from '~/utils/package-name'

const props = defineProps<{
packageName: string
packageScope?: string | null
canPublishToScope: boolean
}>()

const {
Expand Down Expand Up @@ -221,9 +223,19 @@ const previewPackageJson = computed(() => {
</div>

<!-- Availability status -->
<div v-if="checkResult.valid">
<template v-if="checkResult.valid">
<div
v-if="checkResult.available"
v-if="isConnected && !canPublishToScope"
class="flex items-center gap-3 p-4 bg-red-500/10 border border-red-500/20 rounded-lg"
>
<span class="i-lucide:x text-red-500 w-5 h-5" aria-hidden="true" />
<p class="font-mono text-sm text-fg">
{{ $t('claim.modal.missing_permission', { scope: packageScope }) }}
</p>
</div>

<div
v-else-if="checkResult.available"
class="flex items-center gap-3 p-4 bg-green-500/10 border border-green-500/20 rounded-lg"
>
<span class="i-lucide:check text-green-500 w-5 h-5" aria-hidden="true" />
Expand All @@ -237,10 +249,10 @@ const previewPackageJson = computed(() => {
<span class="i-lucide:x text-red-500 w-5 h-5" aria-hidden="true" />
<p class="font-mono text-sm text-fg">{{ $t('claim.modal.taken') }}</p>
</div>
</div>
</template>

<!-- Similar packages warning -->
<div v-if="checkResult.similarPackages?.length && checkResult.available">
<template v-if="checkResult.similarPackages?.length && checkResult.available">
<div
:class="
hasDangerousSimilarPackages
Expand Down Expand Up @@ -290,7 +302,7 @@ const previewPackageJson = computed(() => {
</li>
</ul>
</div>
</div>
</template>

<!-- Error message -->
<div
Expand Down Expand Up @@ -336,7 +348,7 @@ const previewPackageJson = computed(() => {
</div>

<!-- Claim button -->
<div v-else class="space-y-3">
<div v-else-if="isConnected && canPublishToScope" class="space-y-3">
<p class="text-sm text-fg-muted">
{{ $t('claim.modal.publish_hint') }}
</p>
Expand Down
16 changes: 10 additions & 6 deletions app/pages/search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,13 @@ const canPublishToScope = computed(() => {
return orgMembership.value[scope] === true
})

// Show claim prompt when valid name, available, connected, and has permission
// Show claim prompt when valid name, available, either not connected or connected and has permission
const showClaimPrompt = computed(() => {
return (
isConnected.value &&
isValidPackageName.value &&
packageAvailability.value?.available === true &&
packageAvailability.value.name === query.value.trim() &&
canPublishToScope.value &&
(!isConnected.value || (isConnected.value && canPublishToScope.value)) &&
status.value !== 'pending'
)
})
Expand Down Expand Up @@ -569,7 +568,7 @@ defineOgImageComponent('Default', {
<!-- Claim prompt - shown at top when valid name but no exact match -->
<div
v-if="showClaimPrompt && visibleResults.total > 0"
class="mb-6 p-4 bg-bg-subtle border border-border rounded-lg flex flex-col sm:flex-row sm:items-center gap-3 sm:gap-4"
class="mb-6 p-4 bg-bg-subtle border border-border rounded-lg sm:flex hidden flex-row sm:items-center gap-3 sm:gap-4"
>
<div class="flex-1 min-w-0">
<p class="font-mono text-sm text-fg">
Expand Down Expand Up @@ -687,7 +686,7 @@ defineOgImageComponent('Default', {
</div>

<!-- Offer to claim the package name if it's valid -->
<div v-if="showClaimPrompt" class="max-w-md mx-auto text-center">
<div v-if="showClaimPrompt" class="max-w-md mx-auto text-center hidden sm:block">
<div class="p-4 bg-bg-subtle border border-border rounded-lg">
<p class="text-sm text-fg-muted mb-3">{{ $t('search.want_to_claim') }}</p>
<button
Expand Down Expand Up @@ -741,6 +740,11 @@ defineOgImageComponent('Default', {
</div>

<!-- Claim package modal -->
<PackageClaimPackageModal ref="claimPackageModalRef" :package-name="query" />
<PackageClaimPackageModal
ref="claimPackageModalRef"
:package-name="query"
:package-scope="packageScope"
:can-publish-to-scope="canPublishToScope"
/>
</main>
</template>
1 change: 1 addition & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@
"invalid_name": "Invalid package name:",
"available": "This name is available!",
"taken": "This name is already taken.",
"missing_permission": "You do not have permission to add a package to scope {'@'}{scope}.",
"similar_warning": "Similar packages exist - npm may reject this name:",
"related": "Related packages:",
"scope_warning_title": "Consider using a scoped package instead",
Expand Down
1 change: 1 addition & 0 deletions i18n/locales/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@
"invalid_name": "Nieprawidłowa nazwa pakietu:",
"available": "Ta nazwa jest dostępna!",
"taken": "Ta nazwa jest już zajęta.",
"missing_permission": "Nie masz uprawnień aby dodać pakiet do scope’u {'@'}{scope}.",
"similar_warning": "Istnieją podobne pakiety — npm może odrzucić tę nazwę:",
"related": "Powiązane pakiety:",
"scope_warning_title": "Rozważ użycie pakietu ze scope",
Expand Down
3 changes: 3 additions & 0 deletions i18n/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,9 @@
"taken": {
"type": "string"
},
"missing_permission": {
"type": "string"
},
"similar_warning": {
"type": "string"
},
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/en-GB.json
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@
"invalid_name": "Invalid package name:",
"available": "This name is available!",
"taken": "This name is already taken.",
"missing_permission": "You do not have permission to add a package to scope {'@'}{scope}.",
"similar_warning": "Similar packages exist - npm may reject this name:",
"related": "Related packages:",
"scope_warning_title": "Consider using a scoped package instead",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@
"invalid_name": "Invalid package name:",
"available": "This name is available!",
"taken": "This name is already taken.",
"missing_permission": "You do not have permission to add a package to scope {'@'}{scope}.",
"similar_warning": "Similar packages exist - npm may reject this name:",
"related": "Related packages:",
"scope_warning_title": "Consider using a scoped package instead",
Expand Down
1 change: 1 addition & 0 deletions lunaria/files/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@
"invalid_name": "Nieprawidłowa nazwa pakietu:",
"available": "Ta nazwa jest dostępna!",
"taken": "Ta nazwa jest już zajęta.",
"missing_permission": "Nie masz uprawnień aby dodać pakiet do scope’u {'@'}{scope}.",
"similar_warning": "Istnieją podobne pakiety — npm może odrzucić tę nazwę:",
"related": "Powiązane pakiety:",
"scope_warning_title": "Rozważ użycie pakietu ze scope",
Expand Down
4 changes: 4 additions & 0 deletions test/nuxt/a11y.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,8 @@ describe('component accessibility audits', () => {
const component = await mountSuspended(PackageClaimPackageModal, {
props: {
packageName: 'test-package',
packageScope: undefined,
canPublishToScope: true,
open: false,
},
})
Expand All @@ -1039,6 +1041,8 @@ describe('component accessibility audits', () => {
const component = await mountSuspended(PackageClaimPackageModal, {
props: {
packageName: 'test-package',
packageScope: undefined,
canPublishToScope: true,
open: true,
},
})
Expand Down
Loading