@e-llm-studio/instant-learning 1.3.3 → 1.3.5
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/dist/ILMarketplaceWrapper.js +3 -0
- package/dist/ILMarketplaceWrapper.js.map +1 -1
- package/dist/cjs/ILMarketplaceWrapper.js +3 -0
- package/dist/cjs/ILMarketplaceWrapper.js.map +1 -1
- package/dist/cjs/features/IL-OTJ/ValueTypeWrappers/TeachMePlugin.js +5 -2
- package/dist/cjs/features/IL-OTJ/ValueTypeWrappers/TeachMePlugin.js.map +1 -1
- package/dist/cjs/features/IL-OTJ/_components/ChatComponents/ChatComponent.js +12 -4
- package/dist/cjs/features/IL-OTJ/_components/ChatComponents/ChatComponent.js.map +1 -1
- package/dist/cjs/features/IL-OTJ/_components/ChatComponents/NormalChat.js +13 -4
- package/dist/cjs/features/IL-OTJ/_components/ChatComponents/NormalChat.js.map +1 -1
- package/dist/cjs/features/IL-marketplace/PromoteFlow/EnvironmentConfigurationModal.js +41 -4
- package/dist/cjs/features/IL-marketplace/PromoteFlow/EnvironmentConfigurationModal.js.map +1 -1
- package/dist/cjs/features/IL-marketplace/PromoteFlow/PromoteFlow.js +444 -169
- package/dist/cjs/features/IL-marketplace/PromoteFlow/PromoteFlow.js.map +1 -1
- package/dist/cjs/features/IL-marketplace/PromoteFlow/PromoteFlow.module.css.js +2 -2
- package/dist/cjs/features/IL-marketplace/PromoteFlow/promote-flow.api.js +19 -2
- package/dist/cjs/features/IL-marketplace/PromoteFlow/promote-flow.api.js.map +1 -1
- package/dist/cjs/features/IL-marketplace/PromoteFlow/promote-flow.store.js +7 -0
- package/dist/cjs/features/IL-marketplace/PromoteFlow/promote-flow.store.js.map +1 -1
- package/dist/cjs/features/InstantLearning/InstantLearning.js +1 -0
- package/dist/cjs/features/InstantLearning/InstantLearning.js.map +1 -1
- package/dist/cjs/features/InstantLearning/_components/ChatComponent.js +3 -1
- package/dist/cjs/features/InstantLearning/_components/ChatComponent.js.map +1 -1
- package/dist/cjs/features/InstantLearning/_components/ContextualChatComponent.js +3 -1
- package/dist/cjs/features/InstantLearning/_components/ContextualChatComponent.js.map +1 -1
- package/dist/features/IL-OTJ/ValueTypeWrappers/TeachMePlugin.js +5 -2
- package/dist/features/IL-OTJ/ValueTypeWrappers/TeachMePlugin.js.map +1 -1
- package/dist/features/IL-OTJ/_components/ChatComponents/ChatComponent.js +12 -4
- package/dist/features/IL-OTJ/_components/ChatComponents/ChatComponent.js.map +1 -1
- package/dist/features/IL-OTJ/_components/ChatComponents/NormalChat.js +13 -4
- package/dist/features/IL-OTJ/_components/ChatComponents/NormalChat.js.map +1 -1
- package/dist/features/IL-marketplace/PromoteFlow/EnvironmentConfigurationModal.js +41 -4
- package/dist/features/IL-marketplace/PromoteFlow/EnvironmentConfigurationModal.js.map +1 -1
- package/dist/features/IL-marketplace/PromoteFlow/PromoteFlow.js +446 -171
- package/dist/features/IL-marketplace/PromoteFlow/PromoteFlow.js.map +1 -1
- package/dist/features/IL-marketplace/PromoteFlow/PromoteFlow.module.css.js +2 -2
- package/dist/features/IL-marketplace/PromoteFlow/promote-flow.api.js +17 -3
- package/dist/features/IL-marketplace/PromoteFlow/promote-flow.api.js.map +1 -1
- package/dist/features/IL-marketplace/PromoteFlow/promote-flow.store.js +7 -0
- package/dist/features/IL-marketplace/PromoteFlow/promote-flow.store.js.map +1 -1
- package/dist/features/InstantLearning/InstantLearning.js +1 -0
- package/dist/features/InstantLearning/InstantLearning.js.map +1 -1
- package/dist/features/InstantLearning/_components/ChatComponent.js +3 -1
- package/dist/features/InstantLearning/_components/ChatComponent.js.map +1 -1
- package/dist/features/InstantLearning/_components/ContextualChatComponent.js +3 -1
- package/dist/features/InstantLearning/_components/ContextualChatComponent.js.map +1 -1
- package/dist/types/src/ILMarketplaceWrapper.d.ts.map +1 -1
- package/dist/types/src/features/IL-OTJ/ValueTypeWrappers/TeachMePlugin.d.ts.map +1 -1
- package/dist/types/src/features/IL-OTJ/_components/ChatComponents/ChatComponent.d.ts.map +1 -1
- package/dist/types/src/features/IL-OTJ/_components/ChatComponents/NormalChat.d.ts.map +1 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/EnvironmentConfigurationModal.d.ts.map +1 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/PromoteFlow.d.ts.map +1 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.api.d.ts +5 -2
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.api.d.ts.map +1 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.interfaces.d.ts +26 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.interfaces.d.ts.map +1 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.store.d.ts +3 -1
- package/dist/types/src/features/IL-marketplace/PromoteFlow/promote-flow.store.d.ts.map +1 -1
- package/dist/types/src/features/InstantLearning/InstantLearning.d.ts.map +1 -1
- package/dist/types/src/features/InstantLearning/_components/ChatComponent.d.ts.map +1 -1
- package/dist/types/src/features/InstantLearning/_components/ContextualChatComponent.d.ts.map +1 -1
- package/package.json +4 -5
|
@@ -2,10 +2,10 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useState, useMemo, useEffect } from 'react';
|
|
3
3
|
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
|
-
import { ArrowLeft, ArrowUpRight, ArrowDownUp, Calendar, LoaderCircle, Bell, Copy, ExternalLink, ChevronDown, Settings2 } from 'lucide-react';
|
|
5
|
+
import { ArrowLeft, CircleCheck, Info, ArrowUpRight, ArrowDownUp, Calendar, LoaderCircle, Bell, Copy, ExternalLink, ChevronDown, Settings2 } from 'lucide-react';
|
|
6
6
|
import { getGuidelineTitle, cx } from '../utils.js';
|
|
7
7
|
import { EnvironmentConfigurationModal } from './EnvironmentConfigurationModal.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getSchemaPreview, searchEnvironmentConfigs, getCWUser, getPromotionStatus, getPromotionHistory, startPromotion, checkPromotionPreflight, createEnvironmentConfig, schedulePromotion, triggerScheduledPromotion, rollbackPromotion } from './promote-flow.api.js';
|
|
9
9
|
import { usePromoteFlowStore } from './promote-flow.store.js';
|
|
10
10
|
import { getPromotionResourceId, getEnvironmentDisplayName, getPermittedDestinationTiers, getLatestPromotionForEnvironmentPair, formatPromotionDate, EMPTY_ENVIRONMENT_CONFIGURATION, toCreateEnvironmentConfigRequest, toRegistryRecord } from './promote-flow.utils.js';
|
|
11
11
|
import cssStyles from './PromoteFlow.module.css.js';
|
|
@@ -40,26 +40,21 @@ const ACCORDIONS = [
|
|
|
40
40
|
{
|
|
41
41
|
id: "database",
|
|
42
42
|
title: "Database Details",
|
|
43
|
-
comingSoon:
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
id: "knowledgebase",
|
|
47
|
-
title: "Knowledgebase Details",
|
|
48
|
-
comingSoon: true
|
|
43
|
+
comingSoon: false
|
|
49
44
|
}
|
|
45
|
+
// {
|
|
46
|
+
// id: 'knowledgebase',
|
|
47
|
+
// title: 'Knowledgebase Details',
|
|
48
|
+
// comingSoon: true,
|
|
49
|
+
// },
|
|
50
50
|
];
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"document_feature_configuration",
|
|
57
|
-
"document_feature_techme",
|
|
58
|
-
"document_feature_schema",
|
|
59
|
-
"document_feature_cognitive_compare"
|
|
60
|
-
];
|
|
51
|
+
const isMissingPromotionStatus = (error) => {
|
|
52
|
+
var _a;
|
|
53
|
+
if (error instanceof Error && error.message.includes("404")) return true;
|
|
54
|
+
return typeof error === "object" && error !== null && "response" in error && ((_a = error.response) == null ? void 0 : _a.status) === 404;
|
|
55
|
+
};
|
|
61
56
|
function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
62
|
-
var _a, _b, _c, _d, _e;
|
|
57
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
63
58
|
const [openSections, setOpenSections] = useState({
|
|
64
59
|
overview: true
|
|
65
60
|
});
|
|
@@ -69,13 +64,24 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
69
64
|
);
|
|
70
65
|
const [promotedByName, setPromotedByName] = useState(null);
|
|
71
66
|
const [promotionHistory, setPromotionHistory] = useState([]);
|
|
67
|
+
const [schemaPreview, setSchemaPreview] = useState({});
|
|
68
|
+
const [isLoadingSchemaPreview, setIsLoadingSchemaPreview] = useState(false);
|
|
72
69
|
const [isLoadingHistory, setIsLoadingHistory] = useState(false);
|
|
73
70
|
const [promotionConfigs, setPromotionConfigs] = useState([]);
|
|
74
71
|
const [isLoadingConfigs, setIsLoadingConfigs] = useState(false);
|
|
75
72
|
const [configSearchTier, setConfigSearchTier] = useState(null);
|
|
76
73
|
const [submittingAction, setSubmittingAction] = useState(null);
|
|
74
|
+
const [historyActionTaskId, setHistoryActionTaskId] = useState(null);
|
|
75
|
+
const [isStatusPollingStopped, setIsStatusPollingStopped] = useState(false);
|
|
76
|
+
const [isInitialStatusLoading, setIsInitialStatusLoading] = useState(true);
|
|
77
|
+
const [isCheckingPreflight, setIsCheckingPreflight] = useState(false);
|
|
78
|
+
const [preflightResult, setPreflightResult] = useState(null);
|
|
77
79
|
const sourceEnvironment = usePromoteFlowStore((state) => state.sourceEnvironment);
|
|
78
80
|
const destinationEnvironment = usePromoteFlowStore((state) => state.destinationEnvironment);
|
|
81
|
+
const tenantSourceEnvironment = usePromoteFlowStore((state) => state.tenantSourceEnvironment);
|
|
82
|
+
const tenantDestinationEnvironment = usePromoteFlowStore(
|
|
83
|
+
(state) => state.tenantDestinationEnvironment
|
|
84
|
+
);
|
|
79
85
|
const promotionTask = usePromoteFlowStore((state) => state.promotionTask);
|
|
80
86
|
const promotionResourceId = usePromoteFlowStore((state) => state.promotionResourceId);
|
|
81
87
|
const isSubmitting = usePromoteFlowStore((state) => state.isSubmitting);
|
|
@@ -94,9 +100,14 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
94
100
|
const errorForGuideline = errorResourceId === guidelineResourceId ? error : null;
|
|
95
101
|
const isSourceConfigured = Boolean(sourceEnvironment);
|
|
96
102
|
const isDestinationConfigured = Boolean(destinationEnvironment);
|
|
97
|
-
const canPromote = isSourceConfigured && isDestinationConfigured && !isSubmitting;
|
|
103
|
+
const canPromote = isSourceConfigured && isDestinationConfigured && !isSubmitting && !isInitialStatusLoading;
|
|
98
104
|
const sourceEnvironmentLabel = getEnvironmentDisplayName(sourceEnvironment, "Dev");
|
|
99
105
|
const destinationEnvironmentLabel = getEnvironmentDisplayName(destinationEnvironment, "QA");
|
|
106
|
+
const tenantSourceEnvironmentLabel = getEnvironmentDisplayName(tenantSourceEnvironment, "\u2014");
|
|
107
|
+
const tenantDestinationEnvironmentLabel = getEnvironmentDisplayName(
|
|
108
|
+
tenantDestinationEnvironment,
|
|
109
|
+
"\u2014"
|
|
110
|
+
);
|
|
100
111
|
const isPromoting = Boolean(promotionTaskForGuideline);
|
|
101
112
|
const canRetryPromotion = (promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.status) === "FAILED";
|
|
102
113
|
const sourceTier = (_b = sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier) != null ? _b : "dev";
|
|
@@ -105,7 +116,7 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
105
116
|
[sourceTier]
|
|
106
117
|
);
|
|
107
118
|
const permittedSourceTiers = ["dev", "qa", "prod", "external"];
|
|
108
|
-
const selectedEnvironment = configuredEnvironment === "source" ? sourceEnvironment : destinationEnvironment;
|
|
119
|
+
const selectedEnvironment = configuredEnvironment === "source" ? sourceEnvironment : configuredEnvironment === "destination" ? destinationEnvironment : configuredEnvironment === "tenantSource" ? tenantSourceEnvironment : tenantDestinationEnvironment;
|
|
109
120
|
const latestPromotionForPair = useMemo(
|
|
110
121
|
() => getLatestPromotionForEnvironmentPair(
|
|
111
122
|
promotionHistory,
|
|
@@ -114,6 +125,17 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
114
125
|
),
|
|
115
126
|
[destinationEnvironment, promotionHistory, sourceEnvironment]
|
|
116
127
|
);
|
|
128
|
+
const latestPromotionTaskId = useMemo(() => {
|
|
129
|
+
var _a2;
|
|
130
|
+
const latestPromotion = promotionHistory.reduce(
|
|
131
|
+
(latest, entry) => {
|
|
132
|
+
if (!latest) return entry;
|
|
133
|
+
return Date.parse(entry.updated_at) > Date.parse(latest.updated_at) ? entry : latest;
|
|
134
|
+
},
|
|
135
|
+
null
|
|
136
|
+
);
|
|
137
|
+
return (_a2 = latestPromotion == null ? void 0 : latestPromotion.promotion_task_id) != null ? _a2 : null;
|
|
138
|
+
}, [promotionHistory]);
|
|
117
139
|
const promoteActionLabel = (latestPromotionForPair == null ? void 0 : latestPromotionForPair.status) === "SUCCESS" ? "Sync" : "Promote Now";
|
|
118
140
|
const toggleSection = (id) => {
|
|
119
141
|
setOpenSections((current) => ({ ...current, [id]: !current[id] }));
|
|
@@ -121,33 +143,77 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
121
143
|
useEffect(() => {
|
|
122
144
|
let isCurrent = true;
|
|
123
145
|
setIsLoadingHistory(true);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
setIsInitialStatusLoading(true);
|
|
147
|
+
setError(null);
|
|
148
|
+
setPromotionTask(null);
|
|
149
|
+
const refreshInitialPromotionState = async () => {
|
|
150
|
+
try {
|
|
151
|
+
await getPromotionStatus(guidelineResourceId);
|
|
152
|
+
} catch (statusError) {
|
|
153
|
+
if (isCurrent && !isMissingPromotionStatus(statusError)) {
|
|
154
|
+
setError(
|
|
155
|
+
statusError instanceof Error ? statusError.message : "Unable to refresh promotion status.",
|
|
156
|
+
guidelineResourceId
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
} finally {
|
|
160
|
+
if (isCurrent) setIsInitialStatusLoading(false);
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const history = await getPromotionHistory(guidelineResourceId);
|
|
164
|
+
if (isCurrent) setPromotionHistory(history);
|
|
165
|
+
} catch (historyError) {
|
|
166
|
+
if (isCurrent) {
|
|
167
|
+
setError(
|
|
168
|
+
historyError instanceof Error ? historyError.message : "Unable to load promotion history.",
|
|
169
|
+
guidelineResourceId
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
} finally {
|
|
173
|
+
if (isCurrent) setIsLoadingHistory(false);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
void refreshInitialPromotionState();
|
|
177
|
+
return () => {
|
|
178
|
+
isCurrent = false;
|
|
179
|
+
};
|
|
180
|
+
}, [guidelineResourceId, setError, setPromotionTask]);
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
let isCurrent = true;
|
|
183
|
+
setIsLoadingSchemaPreview(true);
|
|
184
|
+
getSchemaPreview(guidelineResourceId).then((preview) => {
|
|
185
|
+
if (!isCurrent) return;
|
|
186
|
+
setSchemaPreview(
|
|
187
|
+
Object.entries(preview != null ? preview : {}).reduce((groups, [key, value]) => {
|
|
188
|
+
if (value && Array.isArray(value.tables)) groups[key] = value;
|
|
189
|
+
return groups;
|
|
190
|
+
}, {})
|
|
191
|
+
);
|
|
192
|
+
}).catch((schemaError) => {
|
|
127
193
|
if (isCurrent) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
guidelineResourceId
|
|
131
|
-
);
|
|
194
|
+
console.error("Failed to load schema preview", { resourceId: guidelineResourceId, schemaError });
|
|
195
|
+
setSchemaPreview({});
|
|
132
196
|
}
|
|
133
197
|
}).finally(() => {
|
|
134
|
-
if (isCurrent)
|
|
198
|
+
if (isCurrent) setIsLoadingSchemaPreview(false);
|
|
135
199
|
});
|
|
136
200
|
return () => {
|
|
137
201
|
isCurrent = false;
|
|
138
202
|
};
|
|
139
|
-
}, [guidelineResourceId
|
|
203
|
+
}, [guidelineResourceId]);
|
|
140
204
|
useEffect(() => {
|
|
141
|
-
var _a2, _b2;
|
|
205
|
+
var _a2, _b2, _c2, _d2;
|
|
142
206
|
if (!configuredEnvironment) return;
|
|
143
|
-
const
|
|
207
|
+
const selectedEnvironment2 = configuredEnvironment === "source" ? (_a2 = sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier) != null ? _a2 : "dev" : configuredEnvironment === "destination" ? (_b2 = destinationEnvironment == null ? void 0 : destinationEnvironment.env_tier) != null ? _b2 : permittedDestinationTiers[0] : configuredEnvironment === "tenantSource" ? (_c2 = tenantSourceEnvironment == null ? void 0 : tenantSourceEnvironment.env_tier) != null ? _c2 : "dev" : (_d2 = tenantDestinationEnvironment == null ? void 0 : tenantDestinationEnvironment.env_tier) != null ? _d2 : permittedDestinationTiers[0];
|
|
208
|
+
const defaultTier = selectedEnvironment2;
|
|
144
209
|
const envTier = configSearchTier != null ? configSearchTier : defaultTier;
|
|
145
210
|
let isCurrent = true;
|
|
146
211
|
setIsLoadingConfigs(true);
|
|
147
212
|
setPromotionConfigs([]);
|
|
148
213
|
searchEnvironmentConfigs({
|
|
149
214
|
env_tier: envTier,
|
|
150
|
-
db_type: envTier === "external" ? "EXTERNAL" : "INTERNAL"
|
|
215
|
+
db_type: envTier === "external" ? "EXTERNAL" : "INTERNAL",
|
|
216
|
+
is_tenant: configuredEnvironment === "tenantSource" || configuredEnvironment === "tenantDestination"
|
|
151
217
|
}).then((configs) => {
|
|
152
218
|
if (isCurrent) setPromotionConfigs(configs);
|
|
153
219
|
}).catch(() => {
|
|
@@ -164,7 +230,9 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
164
230
|
destinationEnvironment == null ? void 0 : destinationEnvironment.env_tier,
|
|
165
231
|
guidelineResourceId,
|
|
166
232
|
permittedDestinationTiers,
|
|
167
|
-
sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier
|
|
233
|
+
sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier,
|
|
234
|
+
tenantDestinationEnvironment == null ? void 0 : tenantDestinationEnvironment.env_tier,
|
|
235
|
+
tenantSourceEnvironment == null ? void 0 : tenantSourceEnvironment.env_tier
|
|
168
236
|
]);
|
|
169
237
|
useEffect(() => {
|
|
170
238
|
const promotedByEmail = promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.created_by;
|
|
@@ -187,11 +255,14 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
187
255
|
};
|
|
188
256
|
}, [promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.created_by, promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.promotion_task_id]);
|
|
189
257
|
useEffect(() => {
|
|
190
|
-
if (!promotionTaskForGuideline ||
|
|
258
|
+
if (!promotionTaskForGuideline || isStatusPollingStopped || !["MIGRATING", "ROLLBACK_IN_PROGRESS"].includes(promotionTaskForGuideline.status)) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
191
261
|
const pollStatus = async () => {
|
|
192
262
|
try {
|
|
193
|
-
setPromotionTask(await getPromotionStatus(
|
|
263
|
+
setPromotionTask(await getPromotionStatus(guidelineResourceId), guidelineResourceId);
|
|
194
264
|
} catch (pollError) {
|
|
265
|
+
setIsStatusPollingStopped(true);
|
|
195
266
|
setError(
|
|
196
267
|
pollError instanceof Error ? pollError.message : "Unable to refresh promotion status.",
|
|
197
268
|
guidelineResourceId
|
|
@@ -200,7 +271,7 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
200
271
|
};
|
|
201
272
|
const intervalId = window.setInterval(pollStatus, 3e4);
|
|
202
273
|
return () => window.clearInterval(intervalId);
|
|
203
|
-
}, [guidelineResourceId, promotionTaskForGuideline, setError, setPromotionTask]);
|
|
274
|
+
}, [guidelineResourceId, isStatusPollingStopped, promotionTaskForGuideline, setError, setPromotionTask]);
|
|
204
275
|
const handlePromoteNow = async () => {
|
|
205
276
|
if (!canPromote || !sourceEnvironment || !destinationEnvironment) return;
|
|
206
277
|
setSubmitting(true);
|
|
@@ -212,9 +283,18 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
212
283
|
resource_type: "PACKAGE",
|
|
213
284
|
target_version: "latest",
|
|
214
285
|
global_source_env_id: sourceEnvironment.env_id,
|
|
215
|
-
global_target_env_id: destinationEnvironment.env_id
|
|
286
|
+
global_target_env_id: destinationEnvironment.env_id,
|
|
287
|
+
...tenantSourceEnvironment && tenantDestinationEnvironment ? {
|
|
288
|
+
tenant_source_env_id: tenantSourceEnvironment.env_id,
|
|
289
|
+
tenant_target_env_id: tenantDestinationEnvironment.env_id
|
|
290
|
+
} : {}
|
|
216
291
|
});
|
|
292
|
+
setIsStatusPollingStopped(false);
|
|
217
293
|
setPromotionTask(task, guidelineResourceId);
|
|
294
|
+
try {
|
|
295
|
+
setPromotionTask(await getPromotionStatus(guidelineResourceId), guidelineResourceId);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
}
|
|
218
298
|
onPromote == null ? void 0 : onPromote(guideline);
|
|
219
299
|
} catch (promotionError) {
|
|
220
300
|
setError(
|
|
@@ -226,15 +306,53 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
226
306
|
setSubmittingAction(null);
|
|
227
307
|
}
|
|
228
308
|
};
|
|
309
|
+
const handlePreflightCheck = async () => {
|
|
310
|
+
if (!sourceEnvironment || !destinationEnvironment || isCheckingPreflight) return;
|
|
311
|
+
setIsCheckingPreflight(true);
|
|
312
|
+
setPreflightResult(null);
|
|
313
|
+
setError(null);
|
|
314
|
+
try {
|
|
315
|
+
const result = await checkPromotionPreflight({
|
|
316
|
+
resource_id: guidelineResourceId,
|
|
317
|
+
resource_type: "PACKAGE",
|
|
318
|
+
target_version: "latest",
|
|
319
|
+
global_source_env_id: sourceEnvironment.env_id,
|
|
320
|
+
global_target_env_id: destinationEnvironment.env_id,
|
|
321
|
+
...tenantSourceEnvironment && tenantDestinationEnvironment ? {
|
|
322
|
+
tenant_source_env_id: tenantSourceEnvironment.env_id,
|
|
323
|
+
tenant_target_env_id: tenantDestinationEnvironment.env_id
|
|
324
|
+
} : {}
|
|
325
|
+
});
|
|
326
|
+
setPreflightResult({
|
|
327
|
+
ready: result.ready,
|
|
328
|
+
itemsChecked: result.items_checked,
|
|
329
|
+
itemsReady: result.items_ready
|
|
330
|
+
});
|
|
331
|
+
} catch (preflightError) {
|
|
332
|
+
setError(
|
|
333
|
+
preflightError instanceof Error ? preflightError.message : "Unable to complete pre-flight check.",
|
|
334
|
+
guidelineResourceId
|
|
335
|
+
);
|
|
336
|
+
} finally {
|
|
337
|
+
setIsCheckingPreflight(false);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
229
340
|
const handleSaveEnvironment = async (environment, configuration) => {
|
|
230
|
-
const
|
|
231
|
-
|
|
341
|
+
const isTenantEnvironment = environment === "tenantSource" || environment === "tenantDestination";
|
|
342
|
+
const configurationToSave = {
|
|
343
|
+
...configuration,
|
|
344
|
+
is_tenant_db: isTenantEnvironment
|
|
345
|
+
};
|
|
346
|
+
const response = await createEnvironmentConfig(
|
|
347
|
+
toCreateEnvironmentConfigRequest(configurationToSave)
|
|
348
|
+
);
|
|
349
|
+
setEnvironment(environment, toRegistryRecord(response.env_id, configurationToSave));
|
|
232
350
|
};
|
|
233
351
|
const openEnvironmentConfiguration = (environment) => {
|
|
234
352
|
var _a2;
|
|
235
|
-
const selected = environment === "source" ? sourceEnvironment : destinationEnvironment;
|
|
353
|
+
const selected = environment === "source" ? sourceEnvironment : environment === "destination" ? destinationEnvironment : environment === "tenantSource" ? tenantSourceEnvironment : tenantDestinationEnvironment;
|
|
236
354
|
setConfigSearchTier(
|
|
237
|
-
(_a2 = selected == null ? void 0 : selected.env_tier) != null ? _a2 : environment === "source" ? "dev" : permittedDestinationTiers[0]
|
|
355
|
+
(_a2 = selected == null ? void 0 : selected.env_tier) != null ? _a2 : environment === "source" || environment === "tenantSource" ? "dev" : permittedDestinationTiers[0]
|
|
238
356
|
);
|
|
239
357
|
setConfiguredEnvironment(environment);
|
|
240
358
|
};
|
|
@@ -250,7 +368,11 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
250
368
|
resource_type: "PACKAGE",
|
|
251
369
|
target_version: "latest",
|
|
252
370
|
global_source_env_id: sourceEnvironment.env_id,
|
|
253
|
-
global_target_env_id: destinationEnvironment.env_id
|
|
371
|
+
global_target_env_id: destinationEnvironment.env_id,
|
|
372
|
+
...tenantSourceEnvironment && tenantDestinationEnvironment ? {
|
|
373
|
+
tenant_source_env_id: tenantSourceEnvironment.env_id,
|
|
374
|
+
tenant_target_env_id: tenantDestinationEnvironment.env_id
|
|
375
|
+
} : {}
|
|
254
376
|
});
|
|
255
377
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
256
378
|
setPromotionTask(
|
|
@@ -285,7 +407,12 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
285
407
|
setError(null);
|
|
286
408
|
try {
|
|
287
409
|
const task = await triggerScheduledPromotion(triggerUrl);
|
|
410
|
+
setIsStatusPollingStopped(false);
|
|
288
411
|
setPromotionTask(task, guidelineResourceId);
|
|
412
|
+
try {
|
|
413
|
+
setPromotionTask(await getPromotionStatus(guidelineResourceId), guidelineResourceId);
|
|
414
|
+
} catch (e) {
|
|
415
|
+
}
|
|
289
416
|
onPromote == null ? void 0 : onPromote(guideline);
|
|
290
417
|
} catch (promotionError) {
|
|
291
418
|
setError(
|
|
@@ -297,7 +424,45 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
297
424
|
setSubmittingAction(null);
|
|
298
425
|
}
|
|
299
426
|
};
|
|
427
|
+
const handleViewPromotionDetails = async (promotionTaskId) => {
|
|
428
|
+
setHistoryActionTaskId(promotionTaskId);
|
|
429
|
+
setError(null);
|
|
430
|
+
try {
|
|
431
|
+
setIsStatusPollingStopped(false);
|
|
432
|
+
setPromotionTask(await getPromotionStatus(guidelineResourceId), guidelineResourceId);
|
|
433
|
+
} catch (statusError) {
|
|
434
|
+
setError(
|
|
435
|
+
statusError instanceof Error ? statusError.message : "Unable to load promotion details.",
|
|
436
|
+
guidelineResourceId
|
|
437
|
+
);
|
|
438
|
+
} finally {
|
|
439
|
+
setHistoryActionTaskId(null);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
const handleRollbackPromotion = async (promotionTaskId) => {
|
|
443
|
+
setHistoryActionTaskId(promotionTaskId);
|
|
444
|
+
setError(null);
|
|
445
|
+
try {
|
|
446
|
+
const task = await rollbackPromotion(promotionTaskId);
|
|
447
|
+
setIsStatusPollingStopped(false);
|
|
448
|
+
setPromotionTask(task, guidelineResourceId);
|
|
449
|
+
} catch (rollbackError) {
|
|
450
|
+
setError(
|
|
451
|
+
rollbackError instanceof Error ? rollbackError.message : "Unable to start rollback.",
|
|
452
|
+
guidelineResourceId
|
|
453
|
+
);
|
|
454
|
+
} finally {
|
|
455
|
+
setHistoryActionTaskId(null);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
300
458
|
const handleBack = () => {
|
|
459
|
+
if (promotionTaskForGuideline) {
|
|
460
|
+
setPromotionTask(null);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
handleGoToMarketplace();
|
|
464
|
+
};
|
|
465
|
+
const handleGoToMarketplace = () => {
|
|
301
466
|
if ((promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.status) === "FAILED") {
|
|
302
467
|
resetPromotionSession();
|
|
303
468
|
}
|
|
@@ -318,63 +483,90 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
318
483
|
};
|
|
319
484
|
const renderAccordionBody = (id) => {
|
|
320
485
|
if (id === "overview") {
|
|
321
|
-
return /* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */ jsxs("div", {
|
|
323
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
324
|
-
/* @__PURE__ */
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
)
|
|
340
|
-
] }),
|
|
341
|
-
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: sourceEnvironmentLabel })
|
|
486
|
+
return /* @__PURE__ */ jsx("div", { className: cssStyles.overviewPanel, children: /* @__PURE__ */ jsxs("div", { className: cssStyles.overviewGrid, children: [
|
|
487
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
488
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.environmentHeading, children: [
|
|
489
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.metaLabel, children: "Source Environment" }),
|
|
490
|
+
/* @__PURE__ */ jsx(
|
|
491
|
+
"button",
|
|
492
|
+
{
|
|
493
|
+
type: "button",
|
|
494
|
+
className: cx(
|
|
495
|
+
cssStyles.configureEnvironmentButton,
|
|
496
|
+
!isSourceConfigured && cssStyles.configureEnvironmentButtonRequired
|
|
497
|
+
),
|
|
498
|
+
"aria-label": "Configure source environment",
|
|
499
|
+
"data-tooltip": "Configure source environment",
|
|
500
|
+
onClick: () => openEnvironmentConfiguration("source"),
|
|
501
|
+
children: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true", strokeWidth: 2 })
|
|
502
|
+
}
|
|
503
|
+
)
|
|
342
504
|
] }),
|
|
343
|
-
/* @__PURE__ */
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
505
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: sourceEnvironmentLabel })
|
|
506
|
+
] }),
|
|
507
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
508
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.environmentHeading, children: [
|
|
509
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.metaLabel, children: "Destination Environment" }),
|
|
510
|
+
/* @__PURE__ */ jsx(
|
|
511
|
+
"button",
|
|
512
|
+
{
|
|
513
|
+
type: "button",
|
|
514
|
+
className: cx(
|
|
515
|
+
cssStyles.configureEnvironmentButton,
|
|
516
|
+
!isDestinationConfigured && cssStyles.configureEnvironmentButtonRequired
|
|
517
|
+
),
|
|
518
|
+
"aria-label": "Configure destination environment",
|
|
519
|
+
"data-tooltip": "Configure destination environment",
|
|
520
|
+
onClick: () => openEnvironmentConfiguration("destination"),
|
|
521
|
+
children: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true", strokeWidth: 2 })
|
|
522
|
+
}
|
|
523
|
+
)
|
|
362
524
|
] }),
|
|
363
|
-
/* @__PURE__ */
|
|
364
|
-
|
|
365
|
-
|
|
525
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: destinationEnvironmentLabel })
|
|
526
|
+
] }),
|
|
527
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
528
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaLabel, children: "ILKB status" }),
|
|
529
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: statusLabel })
|
|
530
|
+
] }),
|
|
531
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
532
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaLabel, children: "Version" }),
|
|
533
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.versionPill, children: versionLabel })
|
|
534
|
+
] }),
|
|
535
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
536
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.environmentHeading, children: [
|
|
537
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.metaLabel, children: "Tenant Source Environment (optional)" }),
|
|
538
|
+
/* @__PURE__ */ jsx(
|
|
539
|
+
"button",
|
|
540
|
+
{
|
|
541
|
+
type: "button",
|
|
542
|
+
className: cssStyles.configureEnvironmentButton,
|
|
543
|
+
"aria-label": "Configure tenant source environment",
|
|
544
|
+
"data-tooltip": "Configure tenant source environment",
|
|
545
|
+
onClick: () => openEnvironmentConfiguration("tenantSource"),
|
|
546
|
+
children: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true", strokeWidth: 2 })
|
|
547
|
+
}
|
|
548
|
+
)
|
|
366
549
|
] }),
|
|
367
|
-
/* @__PURE__ */
|
|
368
|
-
/* @__PURE__ */ jsx("div", { className: cssStyles.metaLabel, children: "Version" }),
|
|
369
|
-
/* @__PURE__ */ jsx("span", { className: cssStyles.versionPill, children: versionLabel })
|
|
370
|
-
] })
|
|
550
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: tenantSourceEnvironmentLabel })
|
|
371
551
|
] }),
|
|
372
552
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
373
|
-
/* @__PURE__ */
|
|
374
|
-
|
|
375
|
-
|
|
553
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.environmentHeading, children: [
|
|
554
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.metaLabel, children: "Tenant Database Environment (optional)" }),
|
|
555
|
+
/* @__PURE__ */ jsx(
|
|
556
|
+
"button",
|
|
557
|
+
{
|
|
558
|
+
type: "button",
|
|
559
|
+
className: cssStyles.configureEnvironmentButton,
|
|
560
|
+
"aria-label": "Configure tenant database environment",
|
|
561
|
+
"data-tooltip": "Configure tenant database environment",
|
|
562
|
+
onClick: () => openEnvironmentConfiguration("tenantDestination"),
|
|
563
|
+
children: /* @__PURE__ */ jsx(Settings2, { "aria-hidden": "true", strokeWidth: 2 })
|
|
564
|
+
}
|
|
565
|
+
)
|
|
566
|
+
] }),
|
|
567
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaValue, children: tenantDestinationEnvironmentLabel })
|
|
376
568
|
] })
|
|
377
|
-
] });
|
|
569
|
+
] }) });
|
|
378
570
|
}
|
|
379
571
|
if (id === "history") {
|
|
380
572
|
return /* @__PURE__ */ jsx("div", { className: cssStyles.historyPanel, children: /* @__PURE__ */ jsx("div", { className: cssStyles.historyTableWrapper, children: /* @__PURE__ */ jsxs("table", { className: cssStyles.historyTable, children: [
|
|
@@ -387,37 +579,55 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
387
579
|
] }) }),
|
|
388
580
|
/* @__PURE__ */ jsx("tbody", { children: isLoadingHistory ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, children: "Loading promotion history\u2026" }) }) : promotionHistory.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, children: "No promotion history yet." }) }) : promotionHistory.map((row) => {
|
|
389
581
|
var _a2, _b2;
|
|
582
|
+
const canRollback = row.status === "SUCCESS" && row.promotion_task_id === latestPromotionTaskId;
|
|
390
583
|
return /* @__PURE__ */ jsxs("tr", { children: [
|
|
391
584
|
/* @__PURE__ */ jsx("td", { children: row.promotion_task_id }),
|
|
392
585
|
/* @__PURE__ */ jsx("td", { children: (_a2 = row.created_by) != null ? _a2 : "\u2014" }),
|
|
393
586
|
/* @__PURE__ */ jsx("td", { children: (_b2 = row.error_summary) != null ? _b2 : "No errors." }),
|
|
394
587
|
/* @__PURE__ */ jsx("td", { children: formatPromotionDate(row.updated_at) }),
|
|
395
|
-
/* @__PURE__ */
|
|
588
|
+
/* @__PURE__ */ jsxs("td", { children: [
|
|
589
|
+
/* @__PURE__ */ jsx("span", { className: cssStyles.statusPill, children: row.status }),
|
|
590
|
+
/* @__PURE__ */ jsx(
|
|
591
|
+
"button",
|
|
592
|
+
{
|
|
593
|
+
type: "button",
|
|
594
|
+
className: cx(
|
|
595
|
+
cssStyles.tableActionButton,
|
|
596
|
+
canRollback && cssStyles.tableActionButtonDanger
|
|
597
|
+
),
|
|
598
|
+
onClick: () => canRollback ? handleRollbackPromotion(row.promotion_task_id) : handleViewPromotionDetails(row.promotion_task_id),
|
|
599
|
+
disabled: isInitialStatusLoading || historyActionTaskId !== null,
|
|
600
|
+
children: historyActionTaskId === row.promotion_task_id ? canRollback ? "Rolling back\u2026" : "Loading\u2026" : canRollback ? "Rollback" : "View details"
|
|
601
|
+
}
|
|
602
|
+
)
|
|
603
|
+
] })
|
|
396
604
|
] }, row.promotion_task_id);
|
|
397
605
|
}) })
|
|
398
606
|
] }) }) });
|
|
399
607
|
}
|
|
400
608
|
if (id === "database") {
|
|
401
|
-
return /* @__PURE__ */
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
609
|
+
if (isLoadingSchemaPreview) return /* @__PURE__ */ jsx("div", { className: cssStyles.emptyBody, children: "Loading database details\u2026" });
|
|
610
|
+
const groups = Object.entries(schemaPreview);
|
|
611
|
+
if (groups.length === 0) return /* @__PURE__ */ jsx("div", { className: cssStyles.emptyBody, children: "No database details available." });
|
|
612
|
+
return /* @__PURE__ */ jsx("div", { className: cssStyles.databaseGrid, children: groups.flatMap(
|
|
613
|
+
([groupName, group]) => ["Source", "Destination"].map((environment) => /* @__PURE__ */ jsxs("div", { className: cssStyles.databaseCard, children: [
|
|
614
|
+
/* @__PURE__ */ jsxs("h3", { children: [
|
|
615
|
+
environment,
|
|
616
|
+
" Database: ",
|
|
617
|
+
group.database_name
|
|
407
618
|
] }),
|
|
408
|
-
/* @__PURE__ */ jsx("ol", { className: cssStyles.tableList, children: TABLE_NAMES.map((name) => /* @__PURE__ */ jsx("li", { children: name }, name)) }),
|
|
409
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: cssStyles.moreTablesButton, children: "+4 more" })
|
|
410
|
-
] }),
|
|
411
|
-
/* @__PURE__ */ jsxs("div", { className: cssStyles.databaseCard, children: [
|
|
412
|
-
/* @__PURE__ */ jsx("h3", { children: "Destination Database : il-otj-35" }),
|
|
413
619
|
/* @__PURE__ */ jsxs("p", { children: [
|
|
414
620
|
/* @__PURE__ */ jsx(ChevronDown, { className: cssStyles.inlineChevron, strokeWidth: 2 }),
|
|
415
|
-
|
|
621
|
+
groupName,
|
|
622
|
+
" \xB7 ",
|
|
623
|
+
group.schema,
|
|
624
|
+
" \xB7 Tables (",
|
|
625
|
+
group.tables.length,
|
|
626
|
+
")"
|
|
416
627
|
] }),
|
|
417
|
-
/* @__PURE__ */ jsx("ol", { className: cssStyles.tableList, children:
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
] });
|
|
628
|
+
/* @__PURE__ */ jsx("ol", { className: cssStyles.tableList, children: group.tables.map((name) => /* @__PURE__ */ jsx("li", { children: name }, `${groupName}-${environment}-${name}`)) })
|
|
629
|
+
] }, `${groupName}-${environment}`))
|
|
630
|
+
) });
|
|
421
631
|
}
|
|
422
632
|
return /* @__PURE__ */ jsx("div", { className: cssStyles.emptyBody, children: "No details available yet." });
|
|
423
633
|
};
|
|
@@ -431,61 +641,108 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
431
641
|
] }),
|
|
432
642
|
/* @__PURE__ */ jsx("h1", { className: cssStyles.title, children: title })
|
|
433
643
|
] }),
|
|
434
|
-
/* @__PURE__ */
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
644
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.ctaRow, children: [
|
|
645
|
+
/* @__PURE__ */ jsxs("div", { className: cssStyles.preflightAction, children: [
|
|
646
|
+
/* @__PURE__ */ jsx(
|
|
647
|
+
StyledPromoteTooltip,
|
|
648
|
+
{
|
|
649
|
+
title: canPromote ? "Optionally check that this migration is ready before promoting." : "Configure both source and destination environments first.",
|
|
650
|
+
placement: "top",
|
|
651
|
+
arrow: true,
|
|
652
|
+
children: /* @__PURE__ */ jsxs(
|
|
653
|
+
"button",
|
|
654
|
+
{
|
|
655
|
+
type: "button",
|
|
656
|
+
className: cssStyles.secondaryButton,
|
|
657
|
+
onClick: handlePreflightCheck,
|
|
658
|
+
disabled: !canPromote || isCheckingPreflight,
|
|
659
|
+
children: [
|
|
660
|
+
/* @__PURE__ */ jsx(CircleCheck, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
661
|
+
isCheckingPreflight ? "Checking readiness\u2026" : "Check promotion readiness"
|
|
662
|
+
]
|
|
663
|
+
}
|
|
664
|
+
)
|
|
665
|
+
}
|
|
666
|
+
),
|
|
667
|
+
/* @__PURE__ */ jsx(
|
|
668
|
+
StyledPromoteTooltip,
|
|
669
|
+
{
|
|
670
|
+
title: "Runs a safe validation of the selected source and destination environments. It does not start a migration.",
|
|
671
|
+
placement: "top",
|
|
672
|
+
arrow: true,
|
|
673
|
+
children: /* @__PURE__ */ jsx("span", { className: cssStyles.preflightInfo, "aria-label": "About the pre-flight check", children: /* @__PURE__ */ jsx(Info, { className: cssStyles.helpIcon, strokeWidth: 2.2, "aria-hidden": "true" }) })
|
|
674
|
+
}
|
|
675
|
+
)
|
|
676
|
+
] }),
|
|
677
|
+
isPromoting ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
678
|
+
canRetryPromotion && /* @__PURE__ */ jsxs(
|
|
679
|
+
"button",
|
|
680
|
+
{
|
|
681
|
+
type: "button",
|
|
682
|
+
className: cssStyles.primaryButton,
|
|
683
|
+
onClick: handlePromoteNow,
|
|
684
|
+
disabled: !canPromote,
|
|
685
|
+
children: [
|
|
686
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
687
|
+
isSubmitting ? "Starting promotion\u2026" : promoteActionLabel
|
|
688
|
+
]
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ jsxs(
|
|
692
|
+
"button",
|
|
693
|
+
{
|
|
694
|
+
type: "button",
|
|
695
|
+
className: cssStyles.primaryButton,
|
|
696
|
+
onClick: handleGoToMarketplace,
|
|
697
|
+
children: [
|
|
698
|
+
/* @__PURE__ */ jsx(ArrowDownUp, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
699
|
+
"Go to Marketplace"
|
|
700
|
+
]
|
|
701
|
+
}
|
|
702
|
+
)
|
|
703
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
704
|
+
submittingAction !== "now" && /* @__PURE__ */ jsxs(
|
|
705
|
+
"button",
|
|
706
|
+
{
|
|
707
|
+
type: "button",
|
|
708
|
+
className: cssStyles.secondaryButton,
|
|
709
|
+
onClick: handlePromoteLater,
|
|
710
|
+
disabled: !canPromote,
|
|
711
|
+
children: [
|
|
712
|
+
/* @__PURE__ */ jsx(Calendar, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
713
|
+
submittingAction === "later" ? "Scheduling\u2026" : "Promote later"
|
|
714
|
+
]
|
|
715
|
+
}
|
|
716
|
+
),
|
|
717
|
+
submittingAction !== "later" && /* @__PURE__ */ jsx(
|
|
718
|
+
StyledPromoteTooltip,
|
|
719
|
+
{
|
|
720
|
+
title: canPromote ? "" : "Configure both source and destination environments first.",
|
|
721
|
+
disableHoverListener: canPromote,
|
|
722
|
+
placement: "top",
|
|
723
|
+
arrow: true,
|
|
724
|
+
children: /* @__PURE__ */ jsxs(
|
|
725
|
+
"button",
|
|
726
|
+
{
|
|
727
|
+
type: "button",
|
|
728
|
+
className: cssStyles.primaryButton,
|
|
729
|
+
onClick: handlePromoteNow,
|
|
730
|
+
disabled: !canPromote,
|
|
731
|
+
children: [
|
|
732
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
733
|
+
submittingAction === "now" ? "Starting promotion\u2026" : promoteActionLabel
|
|
734
|
+
]
|
|
735
|
+
}
|
|
736
|
+
)
|
|
737
|
+
}
|
|
738
|
+
)
|
|
451
739
|
] })
|
|
452
|
-
] })
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
onClick: handlePromoteLater,
|
|
459
|
-
disabled: !canPromote,
|
|
460
|
-
children: [
|
|
461
|
-
/* @__PURE__ */ jsx(Calendar, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
462
|
-
submittingAction === "later" ? "Scheduling\u2026" : "Promote later"
|
|
463
|
-
]
|
|
464
|
-
}
|
|
465
|
-
),
|
|
466
|
-
submittingAction !== "later" && /* @__PURE__ */ jsx(
|
|
467
|
-
StyledPromoteTooltip,
|
|
468
|
-
{
|
|
469
|
-
title: canPromote ? "" : "Configure both source and destination environments first.",
|
|
470
|
-
disableHoverListener: canPromote,
|
|
471
|
-
placement: "top",
|
|
472
|
-
arrow: true,
|
|
473
|
-
children: /* @__PURE__ */ jsxs(
|
|
474
|
-
"button",
|
|
475
|
-
{
|
|
476
|
-
type: "button",
|
|
477
|
-
className: cssStyles.primaryButton,
|
|
478
|
-
onClick: handlePromoteNow,
|
|
479
|
-
disabled: !canPromote,
|
|
480
|
-
children: [
|
|
481
|
-
/* @__PURE__ */ jsx(ArrowUpRight, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
482
|
-
submittingAction === "now" ? "Starting promotion\u2026" : promoteActionLabel
|
|
483
|
-
]
|
|
484
|
-
}
|
|
485
|
-
)
|
|
486
|
-
}
|
|
487
|
-
)
|
|
488
|
-
] }) })
|
|
740
|
+
] })
|
|
741
|
+
] }),
|
|
742
|
+
preflightResult && /* @__PURE__ */ jsxs("div", { className: cssStyles.preflightSuccess, role: "status", children: [
|
|
743
|
+
"Pre-flight check completed successfully.",
|
|
744
|
+
" ",
|
|
745
|
+
preflightResult.ready ? `Migration is ready (${preflightResult.itemsReady}/${preflightResult.itemsChecked} checks passed).` : `Migration readiness requires attention (${preflightResult.itemsReady}/${preflightResult.itemsChecked} checks passed).`
|
|
489
746
|
] }),
|
|
490
747
|
isPromoting ? /* @__PURE__ */ jsxs("div", { className: cssStyles.promotionStatusBox, children: [
|
|
491
748
|
/* @__PURE__ */ jsx("div", { className: cssStyles.promotionStatusRow, children: /* @__PURE__ */ jsxs("div", { className: cssStyles.promotionStatusRowHeader, children: [
|
|
@@ -540,6 +797,23 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
540
797
|
] })
|
|
541
798
|
] })
|
|
542
799
|
] }),
|
|
800
|
+
(promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.view_detail_url) && /* @__PURE__ */ jsxs("div", { className: cssStyles.promotionDetailsLink, children: [
|
|
801
|
+
/* @__PURE__ */ jsx("div", { className: cssStyles.metaLabel, children: "Promotion details" }),
|
|
802
|
+
/* @__PURE__ */ jsxs(
|
|
803
|
+
"a",
|
|
804
|
+
{
|
|
805
|
+
className: cssStyles.urlLink,
|
|
806
|
+
href: promotionTaskForGuideline.view_detail_url,
|
|
807
|
+
target: "_blank",
|
|
808
|
+
rel: "noreferrer",
|
|
809
|
+
title: promotionTaskForGuideline.view_detail_url,
|
|
810
|
+
children: [
|
|
811
|
+
/* @__PURE__ */ jsx("span", { children: promotionTaskForGuideline.view_detail_url }),
|
|
812
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: cssStyles.urlIcon, strokeWidth: 2 })
|
|
813
|
+
]
|
|
814
|
+
}
|
|
815
|
+
)
|
|
816
|
+
] }),
|
|
543
817
|
(promotionTaskForGuideline == null ? void 0 : promotionTaskForGuideline.status) === "SCHEDULED" && promotionTaskForGuideline.trigger_url && /* @__PURE__ */ jsxs("div", { className: cssStyles.scheduledTrigger, children: [
|
|
544
818
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
545
819
|
/* @__PURE__ */ jsx("div", { className: cssStyles.metaLabel, children: "Scheduled promotion URL" }),
|
|
@@ -549,7 +823,7 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
549
823
|
type: "button",
|
|
550
824
|
className: cssStyles.scheduledTriggerUrl,
|
|
551
825
|
onClick: handleTriggerScheduledPromotion,
|
|
552
|
-
disabled: submittingAction === "trigger",
|
|
826
|
+
disabled: isInitialStatusLoading || submittingAction === "trigger",
|
|
553
827
|
title: promotionTaskForGuideline.trigger_url,
|
|
554
828
|
children: [
|
|
555
829
|
/* @__PURE__ */ jsx("span", { children: promotionTaskForGuideline.trigger_url }),
|
|
@@ -564,7 +838,7 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
564
838
|
type: "button",
|
|
565
839
|
className: cssStyles.primaryButton,
|
|
566
840
|
onClick: handleTriggerScheduledPromotion,
|
|
567
|
-
disabled: submittingAction === "trigger",
|
|
841
|
+
disabled: isInitialStatusLoading || submittingAction === "trigger",
|
|
568
842
|
children: [
|
|
569
843
|
/* @__PURE__ */ jsx(ArrowUpRight, { className: cssStyles.buttonIcon, strokeWidth: 2.2 }),
|
|
570
844
|
submittingAction === "trigger" ? "Starting promotion\u2026" : "Start promotion"
|
|
@@ -624,14 +898,15 @@ function PromoteFlow({ guideline, onBack, onPromote, className }) {
|
|
|
624
898
|
is_tenant_db: selectedEnvironment.is_tenant_db
|
|
625
899
|
} : {
|
|
626
900
|
...EMPTY_ENVIRONMENT_CONFIGURATION,
|
|
627
|
-
env_tier: configuredEnvironment === "source" ? "dev" : permittedDestinationTiers[0],
|
|
628
|
-
db_type: configuredEnvironment === "destination" && permittedDestinationTiers[0] === "external" ? "EXTERNAL" : "INTERNAL"
|
|
901
|
+
env_tier: configuredEnvironment === "source" || configuredEnvironment === "tenantSource" ? "dev" : permittedDestinationTiers[0],
|
|
902
|
+
db_type: (configuredEnvironment === "destination" || configuredEnvironment === "tenantDestination") && permittedDestinationTiers[0] === "external" ? "EXTERNAL" : "INTERNAL",
|
|
903
|
+
is_tenant_db: configuredEnvironment === "tenantSource" || configuredEnvironment === "tenantDestination"
|
|
629
904
|
},
|
|
630
|
-
permittedTiers: configuredEnvironment === "source" ? permittedSourceTiers : permittedDestinationTiers,
|
|
905
|
+
permittedTiers: configuredEnvironment === "source" || configuredEnvironment === "tenantSource" ? permittedSourceTiers : permittedDestinationTiers,
|
|
631
906
|
onSave: handleSaveEnvironment,
|
|
632
907
|
onSelectPreset: setEnvironment,
|
|
633
908
|
onPresetTierChange: setConfigSearchTier,
|
|
634
|
-
presetTier: configSearchTier != null ? configSearchTier : configuredEnvironment === "source" ? (_d = sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier) != null ? _d : "dev" : (_e = destinationEnvironment == null ? void 0 : destinationEnvironment.env_tier) != null ? _e : permittedDestinationTiers[0],
|
|
909
|
+
presetTier: configSearchTier != null ? configSearchTier : configuredEnvironment === "source" ? (_d = sourceEnvironment == null ? void 0 : sourceEnvironment.env_tier) != null ? _d : "dev" : configuredEnvironment === "destination" ? (_e = destinationEnvironment == null ? void 0 : destinationEnvironment.env_tier) != null ? _e : permittedDestinationTiers[0] : configuredEnvironment === "tenantSource" ? (_f = tenantSourceEnvironment == null ? void 0 : tenantSourceEnvironment.env_tier) != null ? _f : "dev" : (_g = tenantDestinationEnvironment == null ? void 0 : tenantDestinationEnvironment.env_tier) != null ? _g : permittedDestinationTiers[0],
|
|
635
910
|
onClose: () => {
|
|
636
911
|
setConfiguredEnvironment(null);
|
|
637
912
|
setConfigSearchTier(null);
|