Polish SEO workspace controls
This commit is contained in:
parent
08894288bc
commit
5ec8e7e691
|
|
@ -1756,7 +1756,16 @@ export function App() {
|
|||
function handlePreviewMessage(event: MessageEvent) {
|
||||
const data = event.data;
|
||||
|
||||
if (!data || typeof data !== "object" || data.type !== "seo-mode:preview-markers") {
|
||||
if (!data || typeof data !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.type === "seo-mode:preview-pointerdown") {
|
||||
closeWorkspacePageMenus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.type !== "seo-mode:preview-markers") {
|
||||
if (data?.type === "seo-mode:active-scope-page") {
|
||||
const sourceWorkspaceKey = typeof data.workspaceKey === "string" ? data.workspaceKey : "";
|
||||
const pageId = typeof data.pageId === "string" ? data.pageId : "";
|
||||
|
|
@ -2597,6 +2606,42 @@ export function App() {
|
|||
}));
|
||||
}
|
||||
|
||||
function closeWorkspacePageMenus() {
|
||||
setWorkspacePageMenus((currentMenus) => {
|
||||
let hasOpenMenu = false;
|
||||
const nextMenus = { ...currentMenus };
|
||||
|
||||
Object.keys(nextMenus).forEach((workspaceKey) => {
|
||||
if (nextMenus[workspaceKey]) {
|
||||
nextMenus[workspaceKey] = false;
|
||||
hasOpenMenu = true;
|
||||
}
|
||||
});
|
||||
|
||||
return hasOpenMenu ? nextMenus : currentMenus;
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!Object.values(workspacePageMenus).some(Boolean)) {
|
||||
return;
|
||||
}
|
||||
|
||||
function handleDocumentPointerDown(event: PointerEvent) {
|
||||
if (event.target instanceof Element && event.target.closest(".workspace-page-control")) {
|
||||
return;
|
||||
}
|
||||
|
||||
closeWorkspacePageMenus();
|
||||
}
|
||||
|
||||
document.addEventListener("pointerdown", handleDocumentPointerDown, true);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("pointerdown", handleDocumentPointerDown, true);
|
||||
};
|
||||
}, [workspacePageMenus]);
|
||||
|
||||
function updateWorkspacePreviewMarkers(
|
||||
workspaceKey: string,
|
||||
targets: WorkspaceTarget[],
|
||||
|
|
|
|||
|
|
@ -1301,16 +1301,19 @@ export default function ProjectScopeFlow({
|
|||
return (
|
||||
<section className="project-scope-flow-panel">
|
||||
<div className="project-scope-flow-head">
|
||||
<div>
|
||||
<strong>Конфигурация проекта</strong>
|
||||
<small>
|
||||
Выбрано рабочих зон {stats.selectedWorkspaceItems}: посадочных {stats.selectedIndexable}/{stats.indexable},
|
||||
секций {stats.selectedSections}/{stats.enabledSections}, админка {stats.selectedAdmin}/{stats.admin},
|
||||
техслой {stats.selectedTechnical}/{stats.technical}.
|
||||
</small>
|
||||
<strong>Конфигурация проекта</strong>
|
||||
</div>
|
||||
<div className="project-scope-flow-controls">
|
||||
<div className="project-scope-flow-legend">
|
||||
{groups.map((group) => (
|
||||
<span className={`scope-legend-item ${group.scope}`} key={group.scope}>
|
||||
<FileText size={13} />
|
||||
{scopeGroupNames[group.scope]} · {group.selected}/{group.count}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="project-scope-flow-actions">
|
||||
<button disabled={isBusy} onClick={onApplyRecommendedScope} type="button">
|
||||
<button className="active" disabled={isBusy} onClick={onApplyRecommendedScope} type="button">
|
||||
SEO scope
|
||||
</button>
|
||||
<button disabled={isBusy || stats.selectedWorkspaceItems === 0} onClick={onClearSelection} type="button">
|
||||
|
|
@ -1318,14 +1321,6 @@ export default function ProjectScopeFlow({
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="project-scope-flow-legend">
|
||||
{groups.map((group) => (
|
||||
<span className={`scope-legend-item ${group.scope}`} key={group.scope}>
|
||||
<FileText size={13} />
|
||||
{scopeGroupNames[group.scope]} · {group.selected}/{group.count}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="project-scope-flow-canvas">
|
||||
<ReactFlowProvider>
|
||||
<ReactFlow
|
||||
|
|
|
|||
|
|
@ -4543,16 +4543,8 @@ input[type="checkbox"] {
|
|||
}
|
||||
|
||||
.project-scope-flow-head {
|
||||
display: flex;
|
||||
display: block;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.project-scope-flow-head > div:first-child {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
|
|
@ -4562,10 +4554,12 @@ input[type="checkbox"] {
|
|||
font-weight: 780;
|
||||
}
|
||||
|
||||
.project-scope-flow-head small {
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
line-height: 1.35;
|
||||
.project-scope-flow-controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.project-scope-flow-actions {
|
||||
|
|
@ -4576,26 +4570,39 @@ input[type="checkbox"] {
|
|||
}
|
||||
|
||||
.project-scope-flow-actions button {
|
||||
min-height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #202522;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 38px;
|
||||
padding: 0 13px;
|
||||
color: var(--ink);
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.14);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 780;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.project-scope-flow-actions button:first-child {
|
||||
.project-scope-flow-actions button:hover:not(:disabled) {
|
||||
border-color: rgba(24, 32, 29, 0.2);
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.project-scope-flow-actions button.active {
|
||||
color: #ffffff;
|
||||
background: #202522;
|
||||
border-color: #202522;
|
||||
background: var(--ink);
|
||||
border-color: var(--ink);
|
||||
}
|
||||
|
||||
.project-scope-flow-actions button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.48;
|
||||
color: var(--muted);
|
||||
background: #f6f6f7;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.project-scope-flow-legend {
|
||||
|
|
@ -4607,20 +4614,23 @@ input[type="checkbox"] {
|
|||
.scope-legend-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-height: 28px;
|
||||
padding: 0 9px;
|
||||
color: #4d5753;
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 720;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 38px;
|
||||
padding: 0 13px;
|
||||
color: var(--muted);
|
||||
background: #f6f6f7;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scope-legend-item.indexable_page {
|
||||
color: #63300d;
|
||||
border-color: rgba(242, 122, 26, 0.28);
|
||||
color: var(--muted);
|
||||
border-color: var(--line);
|
||||
}
|
||||
|
||||
.project-scope-flow-canvas {
|
||||
|
|
@ -5268,15 +5278,18 @@ input[type="checkbox"] {
|
|||
.page-audit-summary span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-height: 30px;
|
||||
padding: 0 10px;
|
||||
color: var(--ink);
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
min-height: 38px;
|
||||
padding: 0 13px;
|
||||
color: var(--muted);
|
||||
background: #f6f6f7;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.page-audit-list {
|
||||
|
|
@ -6493,14 +6506,13 @@ input[type="checkbox"] {
|
|||
right: 0;
|
||||
z-index: 30;
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
gap: 10px;
|
||||
width: min(380px, calc(100vw - 48px));
|
||||
max-height: min(420px, calc(100vh - 240px));
|
||||
max-height: min(480px, calc(100vh - 180px));
|
||||
padding: 12px;
|
||||
overflow: hidden;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0.72)),
|
||||
rgba(255, 255, 255, 0.94);
|
||||
background: rgba(255, 255, 255, 0.97);
|
||||
border: 1px solid rgba(24, 32, 29, 0.1);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 22px 70px rgba(24, 32, 29, 0.16);
|
||||
|
|
@ -6533,8 +6545,12 @@ input[type="checkbox"] {
|
|||
display: grid;
|
||||
gap: 7px;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
max-height: min(360px, calc(100vh - 260px));
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
padding-right: 2px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button {
|
||||
|
|
@ -6552,8 +6568,14 @@ input[type="checkbox"] {
|
|||
|
||||
.workspace-page-menu-list button:hover,
|
||||
.workspace-page-menu-list button.active {
|
||||
background: #fffaf5;
|
||||
border-color: rgba(242, 122, 26, 0.32);
|
||||
background: #f6f6f7;
|
||||
border-color: rgba(24, 32, 29, 0.16);
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button.active {
|
||||
color: #ffffff;
|
||||
background: var(--ink);
|
||||
border-color: var(--ink);
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button span {
|
||||
|
|
@ -6562,8 +6584,8 @@ input[type="checkbox"] {
|
|||
height: 26px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
background: var(--accent);
|
||||
color: #ffffff;
|
||||
background: var(--ink);
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 850;
|
||||
|
|
@ -6605,6 +6627,21 @@ input[type="checkbox"] {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button.active span {
|
||||
color: var(--ink);
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button.active strong,
|
||||
.workspace-page-menu-list button.active small {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.workspace-page-menu-list button.active em {
|
||||
color: #ffffff;
|
||||
background: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.workspace-current-page-actions .workspace-preview-mode-switch {
|
||||
min-height: 38px;
|
||||
background: #fff !important;
|
||||
|
|
|
|||
|
|
@ -596,6 +596,17 @@ function buildPreviewBridgeScript() {
|
|||
}, "*");
|
||||
}
|
||||
|
||||
function reportPreviewPointerDown() {
|
||||
if (!state.workspaceKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.parent?.postMessage({
|
||||
type: "seo-mode:preview-pointerdown",
|
||||
workspaceKey: state.workspaceKey
|
||||
}, "*");
|
||||
}
|
||||
|
||||
function measure() {
|
||||
const layer = ensureLayer();
|
||||
const root = document.documentElement;
|
||||
|
|
@ -702,6 +713,7 @@ function buildPreviewBridgeScript() {
|
|||
window.addEventListener("resize", scheduleMeasure);
|
||||
window.addEventListener("scroll", scheduleMeasure, { passive: true });
|
||||
document.addEventListener("scroll", scheduleMeasure, { capture: true, passive: true });
|
||||
document.addEventListener("pointerdown", reportPreviewPointerDown, { capture: true, passive: true });
|
||||
window.addEventListener("load", () => {
|
||||
window.setTimeout(scheduleMeasure, 50);
|
||||
window.setTimeout(scheduleMeasure, 500);
|
||||
|
|
|
|||
Loading…
Reference in New Issue