PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
← All changes | js/components/common/Toolbar.tsx +80 -40 3.10.2 → 4.0.0-beta.2 View file →
@@ -1,9 +1,12 @@
1 1 import { __, _x } from '@wordpress/i18n'
2 2 import classnames from 'classnames'
3 3 import React, { useMemo, useState } from 'react'
4 4 import { isLicensed, shouldShowUpsell } from '../../utils/screen'
5 -import { buildUrl } from '../../utils/urls'
5 +import { buildUrl, fetchConstQueryParam } from '../../utils/urls'
6 +import { SUBPAGES, SUBPAGE_ENTRIES, type SubpageName } from '../ManageMenu/subpages'
7 +import { hasSeenDemo } from './demo/useDemoSeen'
8 +import { AiAgentIcon } from './icons/AiAgentIcon'
6 9 import { BlueprintIcon } from './icons/BlueprintIcon'
7 10 import { CommunityIcon } from './icons/CommunityIcon'
8 11 import { LibraryIcon } from './icons/LibraryIcon'
9 12 import { SettingsIcon } from './icons/SettingsIcon'
@@ -10,12 +13,21 @@
10 13 import { SnippetsIcon } from './icons/SnippetsIcon'
11 14 import { UpsellDialog } from './UpsellDialog'
12 15 import type { SVGProps } from 'react'
13 16
14 -export const SUBPAGES = ['snippets', 'blueprints', 'cloud-community', 'cloud-library'] as const
17 +const searchParams = new URLSearchParams(window.location.search)
15 18
16 -const searchParams = new URLSearchParams(window.location.search)
19 +const managePageSlug = window.CODE_SNIPPETS?.urls.manage
20 + ? new URL(window.CODE_SNIPPETS.urls.manage).searchParams.get('page')
21 + : null
17 22
23 +// The manage screen resolves an absent or unrecognised `subpage` to the first subpage, so
24 +// mirror that fallback here — comparing against the raw param would leave every lower-nav
25 +// tab inactive on the default Snippets view, which is where the page opens.
26 +const activeSubpage = searchParams.get('page') === managePageSlug
27 + ? fetchConstQueryParam('subpage', SUBPAGES) ?? SUBPAGES[0]
28 + : null
29 +
18 30 interface UpperNavItemProps {
19 31 name: string
20 32 url: string
21 33 label: string
@@ -39,8 +51,29 @@
39 51 )
40 52 }
41 53 const UpperNavItems = () =>
42 54 <>
55 + {window.CODE_SNIPPETS?.urls.insights && (
56 + <UpperNavItem
57 + name="insights"
58 + url={window.CODE_SNIPPETS.urls.insights}
59 + label={__('Insights', 'code-snippets')}
60 + />)}
61 +
62 + {window.CODE_SNIPPETS?.urls.import && (
63 + <UpperNavItem
64 + name="import-snippets"
65 + url={window.CODE_SNIPPETS.urls.import}
66 + label={_x('Import', 'snippets', 'code-snippets')}
67 + />)}
68 +
69 + {window.CODE_SNIPPETS?.urls.welcome && (
70 + <UpperNavItem
71 + name="welcome"
72 + url={window.CODE_SNIPPETS.urls.welcome}
73 + label={__("What's New", 'code-snippets')}
74 + />)}
75 +
43 76 <UpperNavItem
44 77 name="docs"
45 78 url="https://codesnippets.pro/docs"
46 79 label={__('Docs', 'code-snippets')}
@@ -47,26 +80,12 @@
47 80 />
48 81
49 82 <UpperNavItem
50 83 name="cloud"
51 - url="https://codesnippets.cloud/"
84 + url={window.CODE_SNIPPETS?.urls.cloud ?? 'https://codesnippets.cloud'}
52 85 label={__('Cloud Dashboard', 'code-snippets')}
53 86 />
54 87
55 - {window.CODE_SNIPPETS?.urls.welcome && (
56 - <UpperNavItem
57 - name="welcome"
58 - url={window.CODE_SNIPPETS.urls.welcome}
59 - label={__("What's New", 'code-snippets')}
60 - />)}
61 -
62 - {window.CODE_SNIPPETS?.urls.import && (
63 - <UpperNavItem
64 - name="import-snippets"
65 - url={window.CODE_SNIPPETS.urls.import}
66 - label={_x('Import', 'snippets', 'code-snippets')}
67 - />)}
68 -
69 88 </>
70 89
71 90 const MoreNav = () =>
72 91 <li className="toolbar-more-item">
@@ -123,26 +142,49 @@
123 142 )
124 143 }
125 144
126 145 interface SubpageItemProps {
127 - subpage: typeof SUBPAGES[number]
146 + subpage: SubpageName
128 147 label: string
129 148 Icon: React.FC<SVGProps<SVGSVGElement>>
130 - isPro?: boolean
131 149 }
132 150
133 -const SubpageItem: React.FC<SubpageItemProps> = ({ subpage, label, Icon, isPro }) =>
134 - <li>
135 - <a
136 - href={buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: subpage })}
137 - className={classnames(`${subpage}-link`, { 'active-link': subpage === searchParams.get('subpage') })}
138 - >
139 - <Icon aria-hidden="true" />
140 - <span className="toolbar-nav-label">{label}</span>
141 - {isPro && !isLicensed() && <span className="pro-chip">{__('Pro', 'code-snippets')}</span>}
142 - </a>
143 - </li>
151 +const SubpageItem: React.FC<SubpageItemProps> = ({ subpage, label, Icon }) => {
152 + const { demo, isPro } = SUBPAGE_ENTRIES[subpage]
153 + const isNew = 'announce' === demo && !hasSeenDemo(subpage)
144 154
155 + return (
156 + <li>
157 + <a
158 + href={buildUrl(window.CODE_SNIPPETS?.urls.manage, { subpage: subpage })}
159 + className={classnames(`${subpage}-link`, { 'active-link': subpage === activeSubpage })}
160 + >
161 + <Icon aria-hidden="true" />
162 + <span className="toolbar-nav-label">{label}</span>
163 + {demo && (isNew
164 + ? <span className="new-chip">{__('New', 'code-snippets')}</span>
165 + : <span className="demo-chip">{__('Demo', 'code-snippets')}</span>)}
166 + {isPro && !isLicensed() && <span className="pro-chip">{__('Pro', 'code-snippets')}</span>}
167 + </a>
168 + </li>
169 + )
170 +}
171 +
172 +const SettingsItem = () =>
173 + window.CODE_SNIPPETS?.urls.settings
174 + ? <li>
175 + <a
176 + href={window.CODE_SNIPPETS.urls.settings}
177 + className={classnames('settings-link', {
178 + 'active-link': 'snippets-settings' === searchParams.get('page')
179 + })}
180 + >
181 + <SettingsIcon aria-hidden="true" />
182 + <span className="toolbar-nav-label">{__('Settings', 'code-snippets')}</span>
183 + </a>
184 + </li>
185 + : null
186 +
145 187 const LowerNav = () =>
146 188 <div className="code-snippets-toolbar-lower">
147 189 <nav aria-label={__('Main features', 'code-snippets')}>
148 190 <ul>
@@ -168,9 +210,8 @@
168 210 <SubpageItem
169 211 subpage="cloud-library"
170 212 label={__('Cloud Library', 'code-snippets')}
171 213 Icon={LibraryIcon}
172 - isPro
173 214 />
174 215
175 216 {!isLicensed() && (
176 217 <SubpageItem
@@ -176,18 +217,17 @@
176 217 <SubpageItem
177 218 subpage="blueprints"
178 219 label={__('Blueprints', 'code-snippets')}
179 220 Icon={BlueprintIcon}
180 - isPro
181 221 />)}
182 222
183 - {window.CODE_SNIPPETS?.urls.settings && (
184 - <li className="toolbar-end-item">
185 - <a href={window.CODE_SNIPPETS.urls.settings} className="settings-link">
186 - <SettingsIcon aria-hidden="true" />
187 - <span className="toolbar-nav-label">{__('Settings', 'code-snippets')}</span>
188 - </a>
189 - </li>)}
223 + <SubpageItem
224 + subpage="ai-agent"
225 + label={__('AI Agent', 'code-snippets')}
226 + Icon={AiAgentIcon}
227 + />
228 +
229 + <SettingsItem />
190 230 </ul>
191 231 </nav>
192 232 </div>
193 233