@prenta/admin 1.6.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/__tests__/components/seo-editor-pane.render.test.js +2 -1
- package/dist/__tests__/components/seo-editor-pane.render.test.js.map +1 -1
- package/dist/__tests__/components/seo-issue-fix-panel.render.test.d.ts +2 -0
- package/dist/__tests__/components/seo-issue-fix-panel.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/seo-issue-fix-panel.render.test.js +60 -0
- package/dist/__tests__/components/seo-issue-fix-panel.render.test.js.map +1 -0
- package/dist/__tests__/components/seo-linking-section.render.test.d.ts +2 -0
- package/dist/__tests__/components/seo-linking-section.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/seo-linking-section.render.test.js +94 -0
- package/dist/__tests__/components/seo-linking-section.render.test.js.map +1 -0
- package/dist/__tests__/lib/collection-routes.test.js +8 -1
- package/dist/__tests__/lib/collection-routes.test.js.map +1 -1
- package/dist/__tests__/lib/seo-service-errors.test.js +24 -1
- package/dist/__tests__/lib/seo-service-errors.test.js.map +1 -1
- package/dist/__tests__/views/seo-content-pane.render.test.js +1 -0
- package/dist/__tests__/views/seo-content-pane.render.test.js.map +1 -1
- package/dist/components/seo/SeoEditorPane.d.ts +2 -1
- package/dist/components/seo/SeoEditorPane.d.ts.map +1 -1
- package/dist/components/seo/SeoEditorPane.js +2 -2
- package/dist/components/seo/SeoEditorPane.js.map +1 -1
- package/dist/components/seo/SeoIssueFixPanel.d.ts.map +1 -1
- package/dist/components/seo/SeoIssueFixPanel.js +32 -8
- package/dist/components/seo/SeoIssueFixPanel.js.map +1 -1
- package/dist/components/seo/SeoLinkingSection.d.ts +5 -1
- package/dist/components/seo/SeoLinkingSection.d.ts.map +1 -1
- package/dist/components/seo/SeoLinkingSection.js +50 -3
- package/dist/components/seo/SeoLinkingSection.js.map +1 -1
- package/dist/lib/collection-routes.d.ts +2 -0
- package/dist/lib/collection-routes.d.ts.map +1 -1
- package/dist/lib/collection-routes.js +5 -0
- package/dist/lib/collection-routes.js.map +1 -1
- package/dist/lib/seo-service.d.ts +12 -1
- package/dist/lib/seo-service.d.ts.map +1 -1
- package/dist/lib/seo-service.js +10 -0
- package/dist/lib/seo-service.js.map +1 -1
- package/dist/views/SEO.d.ts.map +1 -1
- package/dist/views/SEO.js +1 -1
- package/dist/views/SEO.js.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.js +1 -1
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.js +1 -1
- package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
- package/dist/views/seo/ContentTab.d.ts +2 -1
- package/dist/views/seo/ContentTab.d.ts.map +1 -1
- package/dist/views/seo/ContentTab.js +2 -2
- package/dist/views/seo/ContentTab.js.map +1 -1
- package/dist/views/seo/LinksTab.d.ts +3 -1
- package/dist/views/seo/LinksTab.d.ts.map +1 -1
- package/dist/views/seo/LinksTab.js +36 -6
- package/dist/views/seo/LinksTab.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/components/seo-editor-pane.render.test.tsx +4 -1
- package/src/__tests__/components/seo-issue-fix-panel.render.test.tsx +65 -0
- package/src/__tests__/components/seo-linking-section.render.test.tsx +146 -0
- package/src/__tests__/lib/collection-routes.test.ts +13 -1
- package/src/__tests__/lib/seo-service-errors.test.ts +29 -0
- package/src/__tests__/views/seo-content-pane.render.test.tsx +1 -0
- package/src/components/seo/SeoEditorPane.tsx +3 -0
- package/src/components/seo/SeoIssueFixPanel.tsx +34 -10
- package/src/components/seo/SeoLinkingSection.tsx +116 -18
- package/src/lib/collection-routes.ts +13 -0
- package/src/lib/seo-service.ts +19 -1
- package/src/views/SEO.tsx +2 -1
- package/src/views/page-editor/PageSectionEditor.tsx +1 -0
- package/src/views/post-editor/PostSectionEditor.tsx +1 -0
- package/src/views/seo/ContentTab.tsx +3 -0
- package/src/views/seo/LinksTab.tsx +108 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinksTab.js","sourceRoot":"","sources":["../../../src/views/seo/LinksTab.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LinksTab.js","sourceRoot":"","sources":["../../../src/views/seo/LinksTab.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prenta/admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"typescript": "^5.7.0",
|
|
100
100
|
"vitest": "^4.1.0",
|
|
101
101
|
"@prenta/component-blocks": "0.3.0",
|
|
102
|
-
"@prenta/core": "4.
|
|
102
|
+
"@prenta/core": "4.2.0",
|
|
103
103
|
"@prenta/plugin-ai": "1.0.0",
|
|
104
104
|
"@prenta/plugin-blocks": "0.2.0",
|
|
105
105
|
"@prenta/plugin-commerce": "0.2.1",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"@prenta/plugin-media": "0.2.0",
|
|
108
108
|
"@prenta/plugin-navigation": "0.3.0",
|
|
109
109
|
"@prenta/plugin-seo": "0.1.1",
|
|
110
|
-
"@prenta/sections-react": "0.17.
|
|
110
|
+
"@prenta/sections-react": "0.17.20"
|
|
111
111
|
},
|
|
112
112
|
"scripts": {
|
|
113
113
|
"build": "tsc --project tsconfig.json && npx @tailwindcss/cli -i src/styles/build-input.css -o dist/prenta-admin.css --minify",
|
|
@@ -61,6 +61,7 @@ vi.mock('../../lib/seo-service.js', () => ({
|
|
|
61
61
|
updateSeoFields: vi.fn(async () => ({})),
|
|
62
62
|
generateSeoField: (field: string, ctx: unknown) => generateSeoField(field, ctx),
|
|
63
63
|
fetchLinkSuggestions: vi.fn(async () => ({ data: { suggestions: [] } })),
|
|
64
|
+
applySeoInternalLink: vi.fn(async () => ({})),
|
|
64
65
|
SEO_SCHEMA_TYPES: ['Article', 'WebPage'],
|
|
65
66
|
}))
|
|
66
67
|
|
|
@@ -81,7 +82,9 @@ beforeEach(() => {
|
|
|
81
82
|
|
|
82
83
|
describe('SeoEditorPane header', () => {
|
|
83
84
|
it('labels the analysis number as "Content analysis N/100", not "Live analysis"', async () => {
|
|
84
|
-
render(
|
|
85
|
+
render(
|
|
86
|
+
<SeoEditorPane entityType="page" entityId="p1" onClose={() => {}} onNavigate={() => {}} />,
|
|
87
|
+
)
|
|
85
88
|
// Score header renders once the record loads.
|
|
86
89
|
expect(await screen.findByText(/SEO score:/)).toBeTruthy()
|
|
87
90
|
await waitFor(() => expect(screen.getByText(/Content analysis 72\/100/)).toBeTruthy())
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import { render, screen } from '@testing-library/react'
|
|
4
|
+
import type { SeoIssue } from '../../lib/seo-service.js'
|
|
5
|
+
|
|
6
|
+
const orphanIssue: SeoIssue = {
|
|
7
|
+
id: 'iss-orphan',
|
|
8
|
+
auditRunId: 'run-1',
|
|
9
|
+
entityType: 'page',
|
|
10
|
+
entityId: 'p1',
|
|
11
|
+
entityTitle: 'Orphan',
|
|
12
|
+
url: '/orphan',
|
|
13
|
+
severity: 'warning',
|
|
14
|
+
category: 'content',
|
|
15
|
+
type: 'orphan-page',
|
|
16
|
+
title: 'Orphan page',
|
|
17
|
+
description: null,
|
|
18
|
+
impact: null,
|
|
19
|
+
recommendation: null,
|
|
20
|
+
status: 'open',
|
|
21
|
+
fixable: true,
|
|
22
|
+
fixActionType: 'insert-link',
|
|
23
|
+
relatedEntityIds: [],
|
|
24
|
+
source: 'audit',
|
|
25
|
+
firstDetectedAt: null,
|
|
26
|
+
lastDetectedAt: null,
|
|
27
|
+
resolvedAt: null,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
vi.mock('../../lib/seo-service.js', async (importOriginal) => {
|
|
31
|
+
const actual = await importOriginal<typeof import('../../lib/seo-service.js')>()
|
|
32
|
+
return {
|
|
33
|
+
...actual,
|
|
34
|
+
fetchSeoIssueFixSuggestion: vi.fn(async () => ({
|
|
35
|
+
suggestion: {
|
|
36
|
+
autoFixable: true,
|
|
37
|
+
source: 'deterministic',
|
|
38
|
+
fixStrategy: 'insert-link',
|
|
39
|
+
fingerprint: 'fp-insert',
|
|
40
|
+
patch: {},
|
|
41
|
+
changes: [],
|
|
42
|
+
justification: 'Add an inbound link from a related page.',
|
|
43
|
+
},
|
|
44
|
+
})),
|
|
45
|
+
applySeoIssueFix: vi.fn(async () => ({})),
|
|
46
|
+
fetchSeoContentBrief: vi.fn(async () => ({})),
|
|
47
|
+
fetchSeoContentResearch: vi.fn(async () => ({})),
|
|
48
|
+
generateSeoContentBrief: vi.fn(async () => ({})),
|
|
49
|
+
ignoreSeoIssue: vi.fn(async () => ({})),
|
|
50
|
+
researchAndBriefSeoIssue: vi.fn(async () => ({})),
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn(), loading: vi.fn() } }))
|
|
55
|
+
|
|
56
|
+
const { SeoIssueFixPanel } = await import('../../components/seo/SeoIssueFixPanel.js')
|
|
57
|
+
|
|
58
|
+
describe('SeoIssueFixPanel insert-link copy', () => {
|
|
59
|
+
it('labels orphan-page insert-link Approve as Approve link, not Approve redirect', async () => {
|
|
60
|
+
render(<SeoIssueFixPanel issue={orphanIssue} expanded />)
|
|
61
|
+
|
|
62
|
+
expect(await screen.findByRole('button', { name: 'Approve link' })).toBeTruthy()
|
|
63
|
+
expect(screen.queryByRole('button', { name: 'Approve redirect' })).toBeNull()
|
|
64
|
+
})
|
|
65
|
+
})
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'
|
|
4
|
+
import type { LinkSuggestion } from '../../lib/seo-service.js'
|
|
5
|
+
|
|
6
|
+
const wrappable: LinkSuggestion = {
|
|
7
|
+
sourceEntityId: 'src-1',
|
|
8
|
+
sourceTitle: 'Related guide',
|
|
9
|
+
sourceUrl: '/guides/related',
|
|
10
|
+
anchorText: 'RankMath',
|
|
11
|
+
confidence: 0.9,
|
|
12
|
+
excerpt: 'We recommend RankMath for on-page SEO.',
|
|
13
|
+
fingerprint: 'fp-1',
|
|
14
|
+
wrappable: true,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const notWrappable: LinkSuggestion = {
|
|
18
|
+
sourceEntityId: 'src-2',
|
|
19
|
+
sourceTitle: 'Other post',
|
|
20
|
+
sourceUrl: '/blog/other',
|
|
21
|
+
anchorText: 'missing phrase',
|
|
22
|
+
confidence: 0.35,
|
|
23
|
+
excerpt: 'This page never mentions the target title.',
|
|
24
|
+
fingerprint: 'fp-2',
|
|
25
|
+
wrappable: false,
|
|
26
|
+
sourceCollection: 'blog',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const fetchLinkSuggestions = vi.fn(async () => ({
|
|
30
|
+
data: {
|
|
31
|
+
target: { id: 'tgt-1', title: 'Orphan', url: '/orphan' },
|
|
32
|
+
suggestions: [wrappable, notWrappable],
|
|
33
|
+
},
|
|
34
|
+
}))
|
|
35
|
+
|
|
36
|
+
const applySeoInternalLink = vi.fn(async () => ({}))
|
|
37
|
+
const fetchPlanInfo = vi.fn(async () => null)
|
|
38
|
+
|
|
39
|
+
vi.mock('../../lib/seo-service.js', () => ({
|
|
40
|
+
fetchLinkSuggestions: () => fetchLinkSuggestions(),
|
|
41
|
+
applySeoInternalLink: () => applySeoInternalLink(),
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
vi.mock('../../lib/plan.js', async (importOriginal) => {
|
|
45
|
+
const actual = await importOriginal<typeof import('../../lib/plan.js')>()
|
|
46
|
+
return {
|
|
47
|
+
...actual,
|
|
48
|
+
fetchPlanInfo: () => fetchPlanInfo(),
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn(), loading: vi.fn() } }))
|
|
53
|
+
|
|
54
|
+
const { SeoLinkingSection } = await import('../../components/seo/SeoLinkingSection.js')
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
fetchLinkSuggestions.mockClear()
|
|
58
|
+
applySeoInternalLink.mockClear()
|
|
59
|
+
fetchPlanInfo.mockClear()
|
|
60
|
+
fetchPlanInfo.mockResolvedValue(null)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe('SeoLinkingSection approve UX', () => {
|
|
64
|
+
it('shows Approve link on wrappable rows and Open in editor on the rest', async () => {
|
|
65
|
+
render(
|
|
66
|
+
<SeoLinkingSection
|
|
67
|
+
entityType="page"
|
|
68
|
+
entityId="tgt-1"
|
|
69
|
+
internalLinks={0}
|
|
70
|
+
externalLinks={0}
|
|
71
|
+
internalLinkOk={false}
|
|
72
|
+
externalLinkOk={false}
|
|
73
|
+
onNavigate={() => {}}
|
|
74
|
+
/>,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
expect(await screen.findByRole('button', { name: 'Approve link' })).toBeTruthy()
|
|
78
|
+
|
|
79
|
+
const wrappableRow = screen.getByText('Related guide').closest('li') as HTMLElement
|
|
80
|
+
expect(within(wrappableRow).getByRole('button', { name: 'Approve link' })).toBeTruthy()
|
|
81
|
+
expect(within(wrappableRow).queryByRole('button', { name: 'Open in editor' })).toBeNull()
|
|
82
|
+
|
|
83
|
+
const otherRow = screen.getByText('Other post').closest('li') as HTMLElement
|
|
84
|
+
expect(within(otherRow).getByRole('button', { name: 'Open in editor' })).toBeTruthy()
|
|
85
|
+
expect(within(otherRow).queryByRole('button', { name: 'Approve link' })).toBeNull()
|
|
86
|
+
|
|
87
|
+
expect(screen.queryByText(/apply links in the content editor/i)).toBeNull()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('hides Approve link and shows upgrade callout when seo.inlineApply is off', async () => {
|
|
91
|
+
render(
|
|
92
|
+
<SeoLinkingSection
|
|
93
|
+
entityType="page"
|
|
94
|
+
entityId="tgt-1"
|
|
95
|
+
internalLinks={0}
|
|
96
|
+
externalLinks={0}
|
|
97
|
+
internalLinkOk={false}
|
|
98
|
+
externalLinkOk={false}
|
|
99
|
+
onNavigate={() => {}}
|
|
100
|
+
planInfo={{
|
|
101
|
+
tier: 'starter',
|
|
102
|
+
features: ['seo.contentBrief'],
|
|
103
|
+
upgradeUrl: 'https://example.com/upgrade',
|
|
104
|
+
}}
|
|
105
|
+
/>,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
expect(await screen.findByText('Related guide')).toBeTruthy()
|
|
109
|
+
expect(screen.queryByRole('button', { name: 'Approve link' })).toBeNull()
|
|
110
|
+
expect(screen.getByText(/Upgrade to unlock SEO inline apply/i)).toBeTruthy()
|
|
111
|
+
|
|
112
|
+
const wrappableRow = screen.getByText('Related guide').closest('li') as HTMLElement
|
|
113
|
+
expect(within(wrappableRow).getByRole('button', { name: 'Open in editor' })).toBeTruthy()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('opens a blog source in the post editor and drops the row after Approve', async () => {
|
|
117
|
+
const onNavigate = vi.fn()
|
|
118
|
+
render(
|
|
119
|
+
<SeoLinkingSection
|
|
120
|
+
entityType="page"
|
|
121
|
+
entityId="tgt-1"
|
|
122
|
+
internalLinks={0}
|
|
123
|
+
externalLinks={0}
|
|
124
|
+
internalLinkOk={false}
|
|
125
|
+
externalLinkOk={false}
|
|
126
|
+
onNavigate={onNavigate}
|
|
127
|
+
planInfo={{
|
|
128
|
+
tier: 'pro',
|
|
129
|
+
features: ['seo.inlineApply'],
|
|
130
|
+
upgradeUrl: null,
|
|
131
|
+
}}
|
|
132
|
+
/>,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
expect(await screen.findByRole('button', { name: 'Approve link' })).toBeTruthy()
|
|
136
|
+
|
|
137
|
+
fireEvent.click(screen.getByRole('button', { name: 'Open in editor' }))
|
|
138
|
+
expect(onNavigate).toHaveBeenCalledWith('/posts/blog/src-2/edit')
|
|
139
|
+
|
|
140
|
+
fireEvent.click(screen.getByRole('button', { name: 'Approve link' }))
|
|
141
|
+
await waitFor(() => {
|
|
142
|
+
expect(applySeoInternalLink).toHaveBeenCalled()
|
|
143
|
+
expect(screen.queryByRole('button', { name: 'Approve link' })).toBeNull()
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
editPathForDoc,
|
|
5
|
+
newPathForCollection,
|
|
6
|
+
sourceEditPath,
|
|
7
|
+
} from '../../lib/collection-routes.js'
|
|
4
8
|
|
|
5
9
|
describe('editPathForDoc', () => {
|
|
6
10
|
it('routes post-type documents to the section editor (not the generic route)', () => {
|
|
@@ -22,6 +26,14 @@ describe('editPathForDoc', () => {
|
|
|
22
26
|
})
|
|
23
27
|
})
|
|
24
28
|
|
|
29
|
+
describe('sourceEditPath', () => {
|
|
30
|
+
it('routes a blog source through CollectionRouteMeta so posts open the post editor', () => {
|
|
31
|
+
expect(sourceEditPath('blog', 'src-2')).toBe('/posts/blog/src-2/edit')
|
|
32
|
+
expect(sourceEditPath('pages', 'abc')).toBe('/pages/abc/edit')
|
|
33
|
+
expect(sourceEditPath(undefined, 'abc')).toBe('/pages/abc/edit')
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
|
|
25
37
|
describe('newPathForCollection', () => {
|
|
26
38
|
it('routes new post documents to the post editor', () => {
|
|
27
39
|
expect(newPathForCollection({ type: 'post' }, 'case-studies')).toBe('/posts/case-studies/new')
|
|
@@ -8,10 +8,12 @@ vi.mock('../../lib/api.js', () => ({
|
|
|
8
8
|
}))
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
|
+
applySeoInternalLink,
|
|
11
12
|
fetchSeoOverview,
|
|
12
13
|
fetchSeoContentRecords,
|
|
13
14
|
fetchSeoIssues,
|
|
14
15
|
fetchRedirectRules,
|
|
16
|
+
isInlineSeoFixIssue,
|
|
15
17
|
runSeoAudit,
|
|
16
18
|
updateSeoFields,
|
|
17
19
|
} = await import('../../lib/seo-service.js')
|
|
@@ -71,6 +73,33 @@ describe('SEO service read fetchers surface errors', () => {
|
|
|
71
73
|
error: 'forbidden',
|
|
72
74
|
})
|
|
73
75
|
})
|
|
76
|
+
|
|
77
|
+
it('applySeoInternalLink POSTs the apply body and returns { error } on failure', async () => {
|
|
78
|
+
cmsApi.mockResolvedValue({ error: 'Not wrappable', status: 422 })
|
|
79
|
+
await expect(
|
|
80
|
+
applySeoInternalLink({
|
|
81
|
+
sourceEntityId: 'src-1',
|
|
82
|
+
targetEntityId: 'tgt-1',
|
|
83
|
+
anchorText: 'RankMath',
|
|
84
|
+
fingerprint: 'fp-1',
|
|
85
|
+
}),
|
|
86
|
+
).resolves.toEqual({ error: 'Not wrappable' })
|
|
87
|
+
expect(cmsApi).toHaveBeenCalledWith('/seo/links/apply', {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
body: JSON.stringify({
|
|
90
|
+
sourceEntityId: 'src-1',
|
|
91
|
+
targetEntityId: 'tgt-1',
|
|
92
|
+
anchorText: 'RankMath',
|
|
93
|
+
fingerprint: 'fp-1',
|
|
94
|
+
}),
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe('inline SEO fix issue types', () => {
|
|
100
|
+
it('treats orphan-page as an inline Approve issue', () => {
|
|
101
|
+
expect(isInlineSeoFixIssue('orphan-page')).toBe(true)
|
|
102
|
+
})
|
|
74
103
|
})
|
|
75
104
|
|
|
76
105
|
describe('SEO audit mutation contract', () => {
|
|
@@ -69,6 +69,7 @@ vi.mock('../../lib/seo-service.js', () => ({
|
|
|
69
69
|
updateSeoFields: (t: string, i: string, p: unknown) => updateSeoFields(t, i, p),
|
|
70
70
|
generateSeoField: vi.fn(async () => ({ unavailable: true })),
|
|
71
71
|
fetchLinkSuggestions: vi.fn(async () => ({ data: { suggestions: [] } })),
|
|
72
|
+
applySeoInternalLink: vi.fn(async () => ({})),
|
|
72
73
|
SEO_SCHEMA_TYPES: ['Article', 'WebPage'],
|
|
73
74
|
applyContentSeoQuery: (
|
|
74
75
|
records: Array<{ entityType: string; title: string }>,
|
|
@@ -162,6 +162,7 @@ export interface SeoEditorPaneProps {
|
|
|
162
162
|
title?: string
|
|
163
163
|
bodyHtml?: string
|
|
164
164
|
featuredImage?: string
|
|
165
|
+
onNavigate?: (path: string) => void
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
export function SeoEditorPane({
|
|
@@ -178,6 +179,7 @@ export function SeoEditorPane({
|
|
|
178
179
|
title,
|
|
179
180
|
bodyHtml,
|
|
180
181
|
featuredImage,
|
|
182
|
+
onNavigate,
|
|
181
183
|
}: SeoEditorPaneProps) {
|
|
182
184
|
const isDraft = !entityId
|
|
183
185
|
const [record, setRecord] = useState<SeoContentRecord | null>(null)
|
|
@@ -994,6 +996,7 @@ export function SeoEditorPane({
|
|
|
994
996
|
externalLinks={Number(externalLinks)}
|
|
995
997
|
internalLinkOk={internalOk}
|
|
996
998
|
externalLinkOk={externalOk}
|
|
999
|
+
onNavigate={onNavigate}
|
|
997
1000
|
/>
|
|
998
1001
|
</SeoAccordionItem>
|
|
999
1002
|
</SeoAccordion>
|
|
@@ -24,6 +24,38 @@ import { hasPlanFeature, type PlanInfo } from '../../lib/plan.js'
|
|
|
24
24
|
import { PlanUpgradeCallout } from '../PlanUpgradeCallout.js'
|
|
25
25
|
import { SeoErrorState, btnPrimary, btnSecondary } from './primitives.js'
|
|
26
26
|
|
|
27
|
+
function approveButtonLabel(strategy: SeoIssueFixSuggestion['fixStrategy']): string {
|
|
28
|
+
switch (strategy) {
|
|
29
|
+
case 'fix-link':
|
|
30
|
+
return 'Fix link in content'
|
|
31
|
+
case 'insert-link':
|
|
32
|
+
return 'Approve link'
|
|
33
|
+
case 'redirect':
|
|
34
|
+
case undefined:
|
|
35
|
+
return 'Approve redirect'
|
|
36
|
+
default: {
|
|
37
|
+
const _exhaustive: never = strategy
|
|
38
|
+
return _exhaustive
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function approveSuccessToast(strategy: SeoIssueFixSuggestion['fixStrategy']): string {
|
|
44
|
+
switch (strategy) {
|
|
45
|
+
case 'fix-link':
|
|
46
|
+
return 'Link updated in content and issue resolved.'
|
|
47
|
+
case 'insert-link':
|
|
48
|
+
return 'Link added and issue resolved.'
|
|
49
|
+
case 'redirect':
|
|
50
|
+
case undefined:
|
|
51
|
+
return 'Redirect created and issue resolved.'
|
|
52
|
+
default: {
|
|
53
|
+
const _exhaustive: never = strategy
|
|
54
|
+
return _exhaustive
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
27
59
|
function formatValue(value: string | boolean | null): string {
|
|
28
60
|
if (value === null || value === '') return '—'
|
|
29
61
|
if (typeof value === 'boolean') return value ? 'Yes' : 'No'
|
|
@@ -321,11 +353,7 @@ export function SeoIssueFixPanel({
|
|
|
321
353
|
toast.error(res.error)
|
|
322
354
|
return
|
|
323
355
|
}
|
|
324
|
-
toast.success(
|
|
325
|
-
suggestion?.fixStrategy === 'fix-link'
|
|
326
|
-
? 'Link updated in content and issue resolved.'
|
|
327
|
-
: 'Redirect created and issue resolved.',
|
|
328
|
-
)
|
|
356
|
+
toast.success(approveSuccessToast(suggestion?.fixStrategy))
|
|
329
357
|
onChanged?.()
|
|
330
358
|
}
|
|
331
359
|
|
|
@@ -491,11 +519,7 @@ export function SeoIssueFixPanel({
|
|
|
491
519
|
disabled={busy}
|
|
492
520
|
>
|
|
493
521
|
<Check className="h-4 w-4" aria-hidden />
|
|
494
|
-
{busy
|
|
495
|
-
? 'Applying…'
|
|
496
|
-
: suggestion.fixStrategy === 'fix-link'
|
|
497
|
-
? 'Fix link in content'
|
|
498
|
-
: 'Approve redirect'}
|
|
522
|
+
{busy ? 'Applying…' : approveButtonLabel(suggestion.fixStrategy)}
|
|
499
523
|
</button>
|
|
500
524
|
) : inlineFix && suggestion?.autoFixable && !inlineApplyEnabled ? (
|
|
501
525
|
<PlanUpgradeCallout feature="seo.inlineApply" upgradeUrl={planInfo?.upgradeUrl} />
|
|
@@ -2,7 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState } from 'react'
|
|
4
4
|
import { Link2, Loader2, Sparkles } from 'lucide-react'
|
|
5
|
-
import {
|
|
5
|
+
import { toast } from 'sonner'
|
|
6
|
+
import { sourceEditPath } from '../../lib/collection-routes.js'
|
|
7
|
+
import {
|
|
8
|
+
applySeoInternalLink,
|
|
9
|
+
fetchLinkSuggestions,
|
|
10
|
+
type LinkSuggestion,
|
|
11
|
+
} from '../../lib/seo-service.js'
|
|
12
|
+
import { fetchPlanInfo, hasPlanFeature, type PlanInfo } from '../../lib/plan.js'
|
|
13
|
+
import { PlanUpgradeCallout } from '../PlanUpgradeCallout.js'
|
|
14
|
+
|
|
15
|
+
const approveBtnCls =
|
|
16
|
+
'inline-flex items-center justify-center gap-1.5 rounded-[7px] bg-primary px-2.5 py-1.5 text-[11.5px] font-medium text-primary-foreground transition-colors hover:opacity-90 focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50'
|
|
17
|
+
|
|
18
|
+
const editorBtnCls =
|
|
19
|
+
'inline-flex items-center justify-center gap-1.5 rounded-[7px] border border-[var(--bdr)] bg-[var(--card)] px-2.5 py-1.5 text-[11.5px] font-medium text-[var(--txt)] transition-colors hover:bg-[var(--acc-l)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none'
|
|
6
20
|
|
|
7
21
|
export function SeoLinkingSection({
|
|
8
22
|
entityType,
|
|
@@ -11,6 +25,8 @@ export function SeoLinkingSection({
|
|
|
11
25
|
externalLinks,
|
|
12
26
|
internalLinkOk,
|
|
13
27
|
externalLinkOk,
|
|
28
|
+
onNavigate,
|
|
29
|
+
planInfo: planInfoProp,
|
|
14
30
|
}: {
|
|
15
31
|
entityType: 'page' | 'post'
|
|
16
32
|
entityId: string | null
|
|
@@ -18,10 +34,31 @@ export function SeoLinkingSection({
|
|
|
18
34
|
externalLinks: number
|
|
19
35
|
internalLinkOk: boolean
|
|
20
36
|
externalLinkOk: boolean
|
|
37
|
+
onNavigate?: (path: string) => void
|
|
38
|
+
/** When omitted (page/post editors), fetched on mount. */
|
|
39
|
+
planInfo?: PlanInfo | null
|
|
21
40
|
}) {
|
|
22
41
|
const [loading, setLoading] = useState(false)
|
|
23
42
|
const [suggestions, setSuggestions] = useState<LinkSuggestion[]>([])
|
|
24
43
|
const [error, setError] = useState<string | null>(null)
|
|
44
|
+
const [applyingKey, setApplyingKey] = useState<string | null>(null)
|
|
45
|
+
const [planInfo, setPlanInfo] = useState<PlanInfo | null | undefined>(planInfoProp)
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (planInfoProp !== undefined) {
|
|
49
|
+
setPlanInfo(planInfoProp)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
let alive = true
|
|
53
|
+
void fetchPlanInfo().then((info) => {
|
|
54
|
+
if (alive) setPlanInfo(info)
|
|
55
|
+
})
|
|
56
|
+
return () => {
|
|
57
|
+
alive = false
|
|
58
|
+
}
|
|
59
|
+
}, [planInfoProp])
|
|
60
|
+
|
|
61
|
+
const inlineApplyEnabled = hasPlanFeature(planInfo, 'seo.inlineApply')
|
|
25
62
|
|
|
26
63
|
useEffect(() => {
|
|
27
64
|
if (!entityId) {
|
|
@@ -48,6 +85,33 @@ export function SeoLinkingSection({
|
|
|
48
85
|
}
|
|
49
86
|
}, [entityType, entityId])
|
|
50
87
|
|
|
88
|
+
async function handleApprove(suggestion: LinkSuggestion) {
|
|
89
|
+
if (!entityId) return
|
|
90
|
+
const key = `${suggestion.sourceEntityId}-${suggestion.fingerprint}`
|
|
91
|
+
setApplyingKey(key)
|
|
92
|
+
const res = await applySeoInternalLink({
|
|
93
|
+
sourceEntityId: suggestion.sourceEntityId,
|
|
94
|
+
targetEntityId: entityId,
|
|
95
|
+
anchorText: suggestion.anchorText,
|
|
96
|
+
fingerprint: suggestion.fingerprint,
|
|
97
|
+
})
|
|
98
|
+
setApplyingKey(null)
|
|
99
|
+
if (res.error) {
|
|
100
|
+
toast.error(res.error)
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
toast.success('Link added.')
|
|
104
|
+
setSuggestions((prev) =>
|
|
105
|
+
prev.filter(
|
|
106
|
+
(row) =>
|
|
107
|
+
!(
|
|
108
|
+
row.fingerprint === suggestion.fingerprint &&
|
|
109
|
+
row.sourceEntityId === suggestion.sourceEntityId
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
51
115
|
return (
|
|
52
116
|
<div className="space-y-4">
|
|
53
117
|
<div className="grid grid-cols-2 gap-3">
|
|
@@ -90,22 +154,56 @@ export function SeoLinkingSection({
|
|
|
90
154
|
<Sparkles className="h-3.5 w-3.5 text-[var(--acc)]" aria-hidden />
|
|
91
155
|
Link opportunities
|
|
92
156
|
</div>
|
|
157
|
+
{!inlineApplyEnabled && suggestions.some((s) => s.wrappable) ? (
|
|
158
|
+
<div className="mb-2">
|
|
159
|
+
<PlanUpgradeCallout feature="seo.inlineApply" upgradeUrl={planInfo?.upgradeUrl} />
|
|
160
|
+
</div>
|
|
161
|
+
) : null}
|
|
93
162
|
<ul className="space-y-2">
|
|
94
|
-
{suggestions.map((s) =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
163
|
+
{suggestions.map((s) => {
|
|
164
|
+
const key = `${s.sourceEntityId}-${s.fingerprint || s.anchorText}`
|
|
165
|
+
const busy = applyingKey === key
|
|
166
|
+
return (
|
|
167
|
+
<li
|
|
168
|
+
key={key}
|
|
169
|
+
className="rounded-[7px] border border-[var(--bdr)] bg-[var(--card)] p-2.5"
|
|
170
|
+
>
|
|
171
|
+
<div className="text-[12.5px] font-medium text-[var(--txt)]">{s.sourceTitle}</div>
|
|
172
|
+
<p className="mt-0.5 text-[11px] text-[var(--muted)]">{s.sourceUrl}</p>
|
|
173
|
+
<p className="mt-1 text-[11.5px] text-[var(--sub)]">
|
|
174
|
+
Suggested anchor: <span className="text-[var(--txt)]">{s.anchorText}</span>
|
|
175
|
+
</p>
|
|
176
|
+
{s.excerpt && (
|
|
177
|
+
<p className="mt-1 line-clamp-2 text-[11px] text-[var(--muted)]">{s.excerpt}</p>
|
|
178
|
+
)}
|
|
179
|
+
{s.wrappable && inlineApplyEnabled ? (
|
|
180
|
+
<div className="mt-2">
|
|
181
|
+
<button
|
|
182
|
+
type="button"
|
|
183
|
+
className={approveBtnCls}
|
|
184
|
+
disabled={busy}
|
|
185
|
+
onClick={() => void handleApprove(s)}
|
|
186
|
+
>
|
|
187
|
+
{busy ? <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden /> : null}
|
|
188
|
+
Approve link
|
|
189
|
+
</button>
|
|
190
|
+
</div>
|
|
191
|
+
) : onNavigate ? (
|
|
192
|
+
<div className="mt-2">
|
|
193
|
+
<button
|
|
194
|
+
type="button"
|
|
195
|
+
className={editorBtnCls}
|
|
196
|
+
onClick={() =>
|
|
197
|
+
onNavigate(sourceEditPath(s.sourceCollection, s.sourceEntityId))
|
|
198
|
+
}
|
|
199
|
+
>
|
|
200
|
+
Open in editor
|
|
201
|
+
</button>
|
|
202
|
+
</div>
|
|
203
|
+
) : null}
|
|
204
|
+
</li>
|
|
205
|
+
)
|
|
206
|
+
})}
|
|
109
207
|
</ul>
|
|
110
208
|
</div>
|
|
111
209
|
) : (
|
|
@@ -118,8 +216,8 @@ export function SeoLinkingSection({
|
|
|
118
216
|
<div className="flex items-start gap-2 rounded-[7px] border border-[var(--bdr)] bg-[var(--bg)] p-2.5 text-[11px] text-[var(--sub)]">
|
|
119
217
|
<Link2 className="mt-0.5 h-3.5 w-3.5 shrink-0 text-[var(--acc)]" aria-hidden />
|
|
120
218
|
<span>
|
|
121
|
-
|
|
122
|
-
|
|
219
|
+
Wrappable suggestions can be approved here. Others need an editor pass so we do not invent
|
|
220
|
+
a sentence.
|
|
123
221
|
</span>
|
|
124
222
|
</div>
|
|
125
223
|
</div>
|