dev-preprod-prod logic

This commit is contained in:
2026-03-01 14:39:25 +03:00
parent 165f91b399
commit b7960344e0
13 changed files with 754 additions and 70 deletions

View File

@@ -75,7 +75,9 @@
$: globalEnvironments = $environmentContextStore?.environments || [];
$: globalSelectedEnvId = $environmentContextStore?.selectedEnvId || "";
$: globalSelectedEnv = $selectedEnvironmentStore;
$: isProdContext = Boolean(globalSelectedEnv?.is_production);
$: isProdContext =
String(globalSelectedEnv?.stage || "").toUpperCase() === "PROD" ||
Boolean(globalSelectedEnv?.is_production);
function toggleUserMenu(event) {
event.stopPropagation();
@@ -431,7 +433,7 @@
>
{#each globalEnvironments as env}
<option value={env.id}>
{env.name}{env.is_production ? " [PROD]" : ""}
{env.name}{(String(env.stage || "").toUpperCase() === "PROD" || env.is_production) ? " [PROD]" : ""}
</option>
{/each}
</select>

View File

@@ -136,6 +136,8 @@ export const selectedEnvironmentStore = derived(
export const isProductionContextStore = derived(
selectedEnvironmentStore,
($selectedEnvironment) => Boolean($selectedEnvironment?.is_production),
($selectedEnvironment) =>
String($selectedEnvironment?.stage || "").toUpperCase() === "PROD" ||
Boolean($selectedEnvironment?.is_production),
);
// [/DEF:environmentContext:Store]

View File

@@ -3,12 +3,30 @@
// @PURPOSE: Manages toast notifications using a Svelte writable store.
// @LAYER: UI-State
import { writable } from 'svelte/store';
import { writable } from 'svelte/store';
// [DEF:toasts:Data]
// @PURPOSE: Writable store containing the list of active toasts.
export const toasts = writable([]);
// [/DEF:toasts:Data]
export const toasts = writable([]);
// [/DEF:toasts:Data]
const TOAST_DEDUP_WINDOW_MS = 1200;
const recentToastByKey = new Map();
function buildToastKey(message, type) {
return `${String(type || 'info')}::${String(message || '')}`;
}
function shouldSkipDuplicateToast(message, type) {
const key = buildToastKey(message, type);
const now = Date.now();
const previousAt = recentToastByKey.get(key);
if (previousAt && now - previousAt < TOAST_DEDUP_WINDOW_MS) {
return true;
}
recentToastByKey.set(key, now);
return false;
}
// [DEF:addToast:Function]
// @PURPOSE: Adds a new toast message.
@@ -17,12 +35,16 @@ export const toasts = writable([]);
// @PARAM: message (string) - The message text.
// @PARAM: type (string) - The type of toast (info, success, error).
// @PARAM: duration (number) - Duration in ms before the toast is removed.
export function addToast(message, type = 'info', duration = 3000) {
const id = Math.random().toString(36).substr(2, 9);
console.log(`[toasts.addToast][Action] Adding toast context={{'id': '${id}', 'type': '${type}', 'message': '${message}'}}`);
toasts.update(all => [...all, { id, message, type }]);
setTimeout(() => removeToast(id), duration);
}
export function addToast(message, type = 'info', duration = 3000) {
if (shouldSkipDuplicateToast(message, type)) {
console.log(`[toasts.addToast][Action] Duplicate skipped context={{'type': '${type}', 'message': '${message}'}}`);
return;
}
const id = Math.random().toString(36).substr(2, 9);
console.log(`[toasts.addToast][Action] Adding toast context={{'id': '${id}', 'type': '${type}', 'message': '${message}'}}`);
toasts.update(all => [...all, { id, message, type }]);
setTimeout(() => removeToast(id), duration);
}
// [/DEF:addToast:Function]
// [DEF:removeToast:Function]
@@ -35,4 +57,4 @@ function removeToast(id) {
toasts.update(all => all.filter(t => t.id !== id));
}
// [/DEF:removeToast:Function]
// [/DEF:toasts_module:Module]
// [/DEF:toasts_module:Module]