Clarify keyword snapshot loading state
This commit is contained in:
parent
4d82de82c1
commit
3951a9cbc5
|
|
@ -4379,6 +4379,8 @@ function SeoAnchorReviewWorkspace({
|
||||||
actionKey,
|
actionKey,
|
||||||
activeFilter,
|
activeFilter,
|
||||||
anchorReview,
|
anchorReview,
|
||||||
|
contextProfileLabel,
|
||||||
|
contextProfileStatus,
|
||||||
demandCollectionProfile,
|
demandCollectionProfile,
|
||||||
draftChangeCount,
|
draftChangeCount,
|
||||||
draftDecisionCount,
|
draftDecisionCount,
|
||||||
|
|
@ -4400,6 +4402,8 @@ function SeoAnchorReviewWorkspace({
|
||||||
actionKey: string | null;
|
actionKey: string | null;
|
||||||
activeFilter: AnchorReviewFilter;
|
activeFilter: AnchorReviewFilter;
|
||||||
anchorReview: AnchorReviewContract;
|
anchorReview: AnchorReviewContract;
|
||||||
|
contextProfileLabel: string;
|
||||||
|
contextProfileStatus: "current" | "loading" | "snapshot";
|
||||||
demandCollectionProfile: DemandCollectionProfile;
|
demandCollectionProfile: DemandCollectionProfile;
|
||||||
draftChangeCount: number;
|
draftChangeCount: number;
|
||||||
draftDecisionCount: number;
|
draftDecisionCount: number;
|
||||||
|
|
@ -4441,6 +4445,10 @@ function SeoAnchorReviewWorkspace({
|
||||||
<div>
|
<div>
|
||||||
<strong>Этап 1 · Фиксация семантического базиса</strong>
|
<strong>Этап 1 · Фиксация семантического базиса</strong>
|
||||||
<small>Выбираем смысловые якоря и вручную решаем, что отправлять в очередь Wordstat.</small>
|
<small>Выбираем смысловые якоря и вручную решаем, что отправлять в очередь Wordstat.</small>
|
||||||
|
<small className="keyword-stage-profile-line">
|
||||||
|
Текущий активный профиль: <strong>{contextProfileLabel}</strong>
|
||||||
|
{contextProfileStatus === "loading" ? " · загружается" : contextProfileStatus === "snapshot" ? " · снимок" : ""}
|
||||||
|
</small>
|
||||||
<small>
|
<small>
|
||||||
{getAnchorReviewStateLabel(anchorReview.state)} · очередь Wordstat {anchorReview.readiness.wordstatQueueCount} ·
|
{getAnchorReviewStateLabel(anchorReview.state)} · очередь Wordstat {anchorReview.readiness.wordstatQueueCount} ·
|
||||||
нормализовано: {anchorReview.readiness.normalizedAnchorCount} · предложено:{" "}
|
нормализовано: {anchorReview.readiness.normalizedAnchorCount} · предложено:{" "}
|
||||||
|
|
@ -14288,11 +14296,17 @@ export function App() {
|
||||||
const activeKeywordContextSnapshotDetail = activeKeywordContextSnapshotKey
|
const activeKeywordContextSnapshotDetail = activeKeywordContextSnapshotKey
|
||||||
? (keywordContextSnapshotDetails[activeKeywordContextSnapshotKey] ?? null)
|
? (keywordContextSnapshotDetails[activeKeywordContextSnapshotKey] ?? null)
|
||||||
: null;
|
: null;
|
||||||
|
const isActiveKeywordContextSnapshotReplay = activeKeywordContextSnapshotId !== "current";
|
||||||
|
const isActiveKeywordContextSnapshotPending = Boolean(
|
||||||
|
isActiveKeywordContextSnapshotReplay && !activeKeywordContextSnapshotDetail
|
||||||
|
);
|
||||||
const isActiveKeywordContextSnapshotLoading = Boolean(
|
const isActiveKeywordContextSnapshotLoading = Boolean(
|
||||||
activeKeywordContextSnapshotKey && loadingKeywordContextSnapshotKey === activeKeywordContextSnapshotKey
|
isActiveKeywordContextSnapshotPending ||
|
||||||
|
(activeKeywordContextSnapshotKey && loadingKeywordContextSnapshotKey === activeKeywordContextSnapshotKey)
|
||||||
);
|
);
|
||||||
const activeSemanticAnalysis =
|
const activeSemanticAnalysis =
|
||||||
activeKeywordContextSnapshotDetail?.snapshot.semanticAnalysis ?? (activeProject ? (semanticAnalyses[activeProject.id] ?? null) : null);
|
activeKeywordContextSnapshotDetail?.snapshot.semanticAnalysis ??
|
||||||
|
(isActiveKeywordContextSnapshotPending ? null : activeProject ? (semanticAnalyses[activeProject.id] ?? null) : null);
|
||||||
const activeContextReviewRaw = activeProject ? (contextReviews[activeProject.id] ?? null) : null;
|
const activeContextReviewRaw = activeProject ? (contextReviews[activeProject.id] ?? null) : null;
|
||||||
const activeContextReview =
|
const activeContextReview =
|
||||||
activeSemanticAnalysis && activeContextReviewRaw?.semanticRunId === activeSemanticAnalysis.runId
|
activeSemanticAnalysis && activeContextReviewRaw?.semanticRunId === activeSemanticAnalysis.runId
|
||||||
|
|
@ -14300,10 +14314,11 @@ export function App() {
|
||||||
: null;
|
: null;
|
||||||
const activeMarketEnrichment =
|
const activeMarketEnrichment =
|
||||||
activeKeywordContextSnapshotDetail?.snapshot.marketEnrichment ??
|
activeKeywordContextSnapshotDetail?.snapshot.marketEnrichment ??
|
||||||
(activeProject ? (marketEnrichments[activeProject.id] ?? null) : null);
|
(isActiveKeywordContextSnapshotPending ? null : activeProject ? (marketEnrichments[activeProject.id] ?? null) : null);
|
||||||
const activeKeywordAnalysisWorkflow = activeProject ? (keywordAnalysisWorkflows[activeProject.id] ?? null) : null;
|
const activeKeywordAnalysisWorkflow = activeProject ? (keywordAnalysisWorkflows[activeProject.id] ?? null) : null;
|
||||||
const activeKeywordMap =
|
const activeKeywordMap =
|
||||||
activeKeywordContextSnapshotDetail?.snapshot.keywordMap ?? (activeProject ? (keywordMaps[activeProject.id] ?? null) : null);
|
activeKeywordContextSnapshotDetail?.snapshot.keywordMap ??
|
||||||
|
(isActiveKeywordContextSnapshotPending ? null : activeProject ? (keywordMaps[activeProject.id] ?? null) : null);
|
||||||
const activeQuotaProjectId = activeProject?.id ?? null;
|
const activeQuotaProjectId = activeProject?.id ?? null;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -14884,7 +14899,11 @@ export function App() {
|
||||||
!isPersistingActiveKeywordMap
|
!isPersistingActiveKeywordMap
|
||||||
);
|
);
|
||||||
const isSubmittingActiveKeywordStrategy = isPersistingActiveKeywordMap && persistingKeywordMapMode === "strategy";
|
const isSubmittingActiveKeywordStrategy = isPersistingActiveKeywordMap && persistingKeywordMapMode === "strategy";
|
||||||
const isActiveKeywordContextSnapshotReplay = activeKeywordContextSnapshotId !== "current";
|
const activeKeywordContextSnapshotSummary =
|
||||||
|
activeKeywordContextSnapshotId !== "current"
|
||||||
|
? (activeKeywordContextSnapshotList.find((snapshot) => snapshot.id === activeKeywordContextSnapshotId) ?? null)
|
||||||
|
: null;
|
||||||
|
const activeKeywordContextProfileLabel = activeKeywordContextSnapshotSummary?.label ?? "Текущий контекст";
|
||||||
const activeKeywordContextSnapshotOptions: NdcGlassSelectOption<string>[] = [
|
const activeKeywordContextSnapshotOptions: NdcGlassSelectOption<string>[] = [
|
||||||
{ label: "Текущий контекст", value: "current" },
|
{ label: "Текущий контекст", value: "current" },
|
||||||
...activeKeywordContextSnapshotList.map((snapshot) => ({
|
...activeKeywordContextSnapshotList.map((snapshot) => ({
|
||||||
|
|
@ -14933,7 +14952,7 @@ export function App() {
|
||||||
value={activeKeywordContextSnapshotId}
|
value={activeKeywordContextSnapshotId}
|
||||||
/>
|
/>
|
||||||
{isActiveKeywordContextSnapshotReplay ? (
|
{isActiveKeywordContextSnapshotReplay ? (
|
||||||
<span className="keyword-context-profile-status">
|
<span className="keyword-context-profile-status" title={activeKeywordContextProfileLabel}>
|
||||||
{isActiveKeywordContextSnapshotLoading ? "загружаю снимок" : "снимок"}
|
{isActiveKeywordContextSnapshotLoading ? "загружаю снимок" : "снимок"}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
@ -16467,8 +16486,26 @@ export function App() {
|
||||||
const projectKeywordContextSnapshotDetail = projectKeywordContextSnapshotKey
|
const projectKeywordContextSnapshotDetail = projectKeywordContextSnapshotKey
|
||||||
? (keywordContextSnapshotDetails[projectKeywordContextSnapshotKey] ?? null)
|
? (keywordContextSnapshotDetails[projectKeywordContextSnapshotKey] ?? null)
|
||||||
: null;
|
: null;
|
||||||
|
const projectKeywordContextSnapshotSummary =
|
||||||
|
projectKeywordContextSnapshotId !== "current"
|
||||||
|
? ((keywordContextSnapshots[project.id] ?? []).find(
|
||||||
|
(snapshot) => snapshot.id === projectKeywordContextSnapshotId
|
||||||
|
) ?? null)
|
||||||
|
: null;
|
||||||
|
const projectKeywordContextSnapshotPending = Boolean(
|
||||||
|
projectKeywordContextSnapshotId !== "current" && !projectKeywordContextSnapshotDetail
|
||||||
|
);
|
||||||
|
const projectKeywordContextProfileLabel =
|
||||||
|
projectKeywordContextSnapshotSummary?.label ?? "Текущий контекст";
|
||||||
|
const projectKeywordContextProfileStatus: "current" | "loading" | "snapshot" =
|
||||||
|
projectKeywordContextSnapshotId === "current"
|
||||||
|
? "current"
|
||||||
|
: projectKeywordContextSnapshotPending
|
||||||
|
? "loading"
|
||||||
|
: "snapshot";
|
||||||
const semanticAnalysis =
|
const semanticAnalysis =
|
||||||
projectKeywordContextSnapshotDetail?.snapshot.semanticAnalysis ?? (semanticAnalyses[project.id] ?? null);
|
projectKeywordContextSnapshotDetail?.snapshot.semanticAnalysis ??
|
||||||
|
(projectKeywordContextSnapshotPending ? null : semanticAnalyses[project.id] ?? null);
|
||||||
const contextReview = contextReviews[project.id] ?? null;
|
const contextReview = contextReviews[project.id] ?? null;
|
||||||
const isContextReviewAligned = Boolean(
|
const isContextReviewAligned = Boolean(
|
||||||
semanticAnalysis && contextReview && contextReview.semanticRunId === semanticAnalysis.runId
|
semanticAnalysis && contextReview && contextReview.semanticRunId === semanticAnalysis.runId
|
||||||
|
|
@ -16476,10 +16513,14 @@ export function App() {
|
||||||
const activeContextReview = isContextReviewAligned ? contextReview : null;
|
const activeContextReview = isContextReviewAligned ? contextReview : null;
|
||||||
const projectOntology = projectOntologies[project.id] ?? null;
|
const projectOntology = projectOntologies[project.id] ?? null;
|
||||||
const marketEnrichment =
|
const marketEnrichment =
|
||||||
projectKeywordContextSnapshotDetail?.snapshot.marketEnrichment ?? (marketEnrichments[project.id] ?? null);
|
projectKeywordContextSnapshotDetail?.snapshot.marketEnrichment ??
|
||||||
|
(projectKeywordContextSnapshotPending ? null : marketEnrichments[project.id] ?? null);
|
||||||
const keywordCleaning =
|
const keywordCleaning =
|
||||||
projectKeywordContextSnapshotDetail?.snapshot.keywordCleaning ?? (keywordCleanings[project.id] ?? null);
|
projectKeywordContextSnapshotDetail?.snapshot.keywordCleaning ??
|
||||||
const keywordMap = projectKeywordContextSnapshotDetail?.snapshot.keywordMap ?? (keywordMaps[project.id] ?? null);
|
(projectKeywordContextSnapshotPending ? null : keywordCleanings[project.id] ?? null);
|
||||||
|
const keywordMap =
|
||||||
|
projectKeywordContextSnapshotDetail?.snapshot.keywordMap ??
|
||||||
|
(projectKeywordContextSnapshotPending ? null : keywordMaps[project.id] ?? null);
|
||||||
const seoStrategy = seoStrategies[project.id] ?? null;
|
const seoStrategy = seoStrategies[project.id] ?? null;
|
||||||
const yandexEvidence = yandexEvidences[project.id] ?? null;
|
const yandexEvidence = yandexEvidences[project.id] ?? null;
|
||||||
const serpInterpretation = serpInterpretations[project.id] ?? null;
|
const serpInterpretation = serpInterpretations[project.id] ?? null;
|
||||||
|
|
@ -16507,7 +16548,8 @@ export function App() {
|
||||||
const isKeywordAnalysisRebuilding = isKeywordAnalysisWorkflowActive(keywordAnalysisWorkflow);
|
const isKeywordAnalysisRebuilding = isKeywordAnalysisWorkflowActive(keywordAnalysisWorkflow);
|
||||||
const anchorReviewDraft = anchorReviewDraftDecisions[project.id] ?? {};
|
const anchorReviewDraft = anchorReviewDraftDecisions[project.id] ?? {};
|
||||||
const rawAnchorReview =
|
const rawAnchorReview =
|
||||||
projectKeywordContextSnapshotDetail?.snapshot.anchorReview ?? marketEnrichment?.anchorReview ?? null;
|
projectKeywordContextSnapshotDetail?.snapshot.anchorReview ??
|
||||||
|
(projectKeywordContextSnapshotPending ? null : marketEnrichment?.anchorReview ?? null);
|
||||||
const anchorReviewDraftCount = getAnchorReviewDraftDecisionList(rawAnchorReview, anchorReviewDraft).length;
|
const anchorReviewDraftCount = getAnchorReviewDraftDecisionList(rawAnchorReview, anchorReviewDraft).length;
|
||||||
const savedDemandCollectionProfile = rawAnchorReview?.demandCollectionProfile ?? "contextual";
|
const savedDemandCollectionProfile = rawAnchorReview?.demandCollectionProfile ?? "contextual";
|
||||||
const anchorReviewDemandProfile =
|
const anchorReviewDemandProfile =
|
||||||
|
|
@ -19536,6 +19578,15 @@ export function App() {
|
||||||
Прошло {keywordBasisElapsedLabel}. Обычно до 8 минут; окно можно оставить открытым.
|
Прошло {keywordBasisElapsedLabel}. Обычно до 8 минут; окно можно оставить открытым.
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
) : projectKeywordContextSnapshotPending ? (
|
||||||
|
<div className="empty-state semantic-empty keyword-context-snapshot-loading">
|
||||||
|
<Loader2 className="spin" size={20} />
|
||||||
|
<strong>Загружаю сохранённый профиль</strong>
|
||||||
|
<span>{projectKeywordContextProfileLabel}</span>
|
||||||
|
<small>
|
||||||
|
Поднимаем сохранённые anchors, Wordstat evidence, cleaning и карту ключей из snapshot.
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{semanticAnalysis && !activeContextReview ? (
|
{semanticAnalysis && !activeContextReview ? (
|
||||||
|
|
@ -19566,6 +19617,8 @@ export function App() {
|
||||||
actionKey={anchorReviewActionKey}
|
actionKey={anchorReviewActionKey}
|
||||||
activeFilter={activeAnchorReviewFilter}
|
activeFilter={activeAnchorReviewFilter}
|
||||||
anchorReview={anchorReview}
|
anchorReview={anchorReview}
|
||||||
|
contextProfileLabel={projectKeywordContextProfileLabel}
|
||||||
|
contextProfileStatus={projectKeywordContextProfileStatus}
|
||||||
draftDecisionCount={anchorReviewDraftCount}
|
draftDecisionCount={anchorReviewDraftCount}
|
||||||
demandCollectionProfile={anchorReviewDemandProfile}
|
demandCollectionProfile={anchorReviewDemandProfile}
|
||||||
draftChangeCount={anchorReviewDraftChangeCount}
|
draftChangeCount={anchorReviewDraftChangeCount}
|
||||||
|
|
|
||||||
|
|
@ -2985,6 +2985,18 @@ input {
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.keyword-stage-heading .keyword-stage-profile-line {
|
||||||
|
color: rgba(10, 12, 14, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyword-stage-heading .keyword-stage-profile-line strong {
|
||||||
|
display: inline;
|
||||||
|
color: var(--ink);
|
||||||
|
font-size: inherit;
|
||||||
|
font-weight: 900;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.keyword-stage-actions {
|
.keyword-stage-actions {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
@ -3117,6 +3129,15 @@ input {
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.keyword-context-snapshot-loading {
|
||||||
|
min-height: 14rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyword-context-snapshot-loading span {
|
||||||
|
max-width: min(48rem, 100%);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
.keyword-workflow-step-list {
|
.keyword-workflow-step-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 7px;
|
gap: 7px;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue