minor UI tweaks
This commit is contained in:
@@ -17,6 +17,8 @@ const DEFAULT_SETTINGS = {
|
|||||||
theme: "system",
|
theme: "system",
|
||||||
toolbarAutoHide: true,
|
toolbarAutoHide: true,
|
||||||
alwaysShowOutput: false,
|
alwaysShowOutput: false,
|
||||||
|
alwaysUseDefaultEnvProfile: false,
|
||||||
|
emptyToolbarBehavior: "open",
|
||||||
workspaces: []
|
workspaces: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -360,6 +360,22 @@ function resolveThemeValue(globalTheme, workspace, site) {
|
|||||||
return globalTheme || "system";
|
return globalTheme || "system";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeEmptyToolbarBehavior(value, allowInherit = true) {
|
||||||
|
if (value === "hide" || value === "open") return value;
|
||||||
|
if (allowInherit && value === "inherit") return "inherit";
|
||||||
|
return allowInherit ? "inherit" : "open";
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveEmptyToolbarBehavior(globalValue, workspace, site) {
|
||||||
|
const base = normalizeEmptyToolbarBehavior(globalValue, false);
|
||||||
|
const workspaceValue = normalizeEmptyToolbarBehavior(
|
||||||
|
workspace?.emptyToolbarBehavior
|
||||||
|
);
|
||||||
|
const workspaceResolved = workspaceValue === "inherit" ? base : workspaceValue;
|
||||||
|
const siteValue = normalizeEmptyToolbarBehavior(site?.emptyToolbarBehavior);
|
||||||
|
return siteValue === "inherit" ? workspaceResolved : siteValue;
|
||||||
|
}
|
||||||
|
|
||||||
function resolveThemeMode(theme) {
|
function resolveThemeMode(theme) {
|
||||||
if (theme === "dark" || theme === "light") return theme;
|
if (theme === "dark" || theme === "light") return theme;
|
||||||
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
@@ -393,10 +409,20 @@ function getToolbarThemeTokens(mode) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createToolbar(shortcuts, position = "bottom-right", themeMode = "light", options = {}) {
|
function createToolbar(
|
||||||
|
shortcuts,
|
||||||
|
position = "bottom-right",
|
||||||
|
themeMode = "light",
|
||||||
|
options = {}
|
||||||
|
) {
|
||||||
let toolbar = document.getElementById("sitecompanion-toolbar");
|
let toolbar = document.getElementById("sitecompanion-toolbar");
|
||||||
if (toolbar) toolbar.remove();
|
if (toolbar) toolbar.remove();
|
||||||
|
|
||||||
|
const hasShortcuts = Array.isArray(shortcuts) && shortcuts.length > 0;
|
||||||
|
const showOpenButton =
|
||||||
|
options?.unknown || (!hasShortcuts && options?.emptyBehavior === "open");
|
||||||
|
if (!hasShortcuts && !showOpenButton) return;
|
||||||
|
|
||||||
toolbar = document.createElement("div");
|
toolbar = document.createElement("div");
|
||||||
toolbar.id = "sitecompanion-toolbar";
|
toolbar.id = "sitecompanion-toolbar";
|
||||||
|
|
||||||
@@ -437,7 +463,7 @@ function createToolbar(shortcuts, position = "bottom-right", themeMode = "light"
|
|||||||
color: ${tokens.ink};
|
color: ${tokens.ink};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (options?.unknown) {
|
if (showOpenButton) {
|
||||||
const btn = document.createElement("button");
|
const btn = document.createElement("button");
|
||||||
btn.type = "button";
|
btn.type = "button";
|
||||||
btn.textContent = "Open SiteCompanion";
|
btn.textContent = "Open SiteCompanion";
|
||||||
@@ -457,12 +483,6 @@ function createToolbar(shortcuts, position = "bottom-right", themeMode = "light"
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
toolbar.appendChild(btn);
|
toolbar.appendChild(btn);
|
||||||
} else if (!shortcuts || !shortcuts.length) {
|
|
||||||
const label = document.createElement("span");
|
|
||||||
label.textContent = "SiteCompanion";
|
|
||||||
label.style.fontSize = "12px";
|
|
||||||
label.style.color = tokens.muted;
|
|
||||||
toolbar.appendChild(label);
|
|
||||||
} else {
|
} else {
|
||||||
for (const shortcut of shortcuts) {
|
for (const shortcut of shortcuts) {
|
||||||
const btn = document.createElement("button");
|
const btn = document.createElement("button");
|
||||||
@@ -527,7 +547,8 @@ async function refreshToolbar() {
|
|||||||
presets = [],
|
presets = [],
|
||||||
toolbarPosition = "bottom-right",
|
toolbarPosition = "bottom-right",
|
||||||
theme = "system",
|
theme = "system",
|
||||||
toolbarAutoHide = true
|
toolbarAutoHide = true,
|
||||||
|
emptyToolbarBehavior = "open"
|
||||||
} = await chrome.storage.local.get([
|
} = await chrome.storage.local.get([
|
||||||
"sites",
|
"sites",
|
||||||
"workspaces",
|
"workspaces",
|
||||||
@@ -535,7 +556,8 @@ async function refreshToolbar() {
|
|||||||
"presets",
|
"presets",
|
||||||
"toolbarPosition",
|
"toolbarPosition",
|
||||||
"theme",
|
"theme",
|
||||||
"toolbarAutoHide"
|
"toolbarAutoHide",
|
||||||
|
"emptyToolbarBehavior"
|
||||||
]);
|
]);
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href;
|
||||||
const site = sites.find(s => matchUrl(currentUrl, s.urlPattern));
|
const site = sites.find(s => matchUrl(currentUrl, s.urlPattern));
|
||||||
@@ -579,7 +601,19 @@ async function refreshToolbar() {
|
|||||||
: toolbarPosition;
|
: toolbarPosition;
|
||||||
const resolvedTheme = resolveThemeValue(theme, workspace, site);
|
const resolvedTheme = resolveThemeValue(theme, workspace, site);
|
||||||
const themeMode = resolveThemeMode(resolvedTheme);
|
const themeMode = resolveThemeMode(resolvedTheme);
|
||||||
createToolbar(siteShortcuts, resolvedPosition, themeMode);
|
const resolvedEmptyToolbarBehavior = resolveEmptyToolbarBehavior(
|
||||||
|
emptyToolbarBehavior,
|
||||||
|
workspace,
|
||||||
|
site
|
||||||
|
);
|
||||||
|
if (!siteShortcuts.length && resolvedEmptyToolbarBehavior === "hide") {
|
||||||
|
const toolbar = document.getElementById("sitecompanion-toolbar");
|
||||||
|
if (toolbar) toolbar.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
createToolbar(siteShortcuts, resolvedPosition, themeMode, {
|
||||||
|
emptyBehavior: resolvedEmptyToolbarBehavior
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = String(error?.message || "");
|
const message = String(error?.message || "");
|
||||||
if (message.includes("Extension context invalidated")) {
|
if (message.includes("Extension context invalidated")) {
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ body {
|
|||||||
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
|
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
background: var(--page-bg);
|
background: var(--page-bg);
|
||||||
--output-max-height-base: 280px;
|
--control-height: 30px;
|
||||||
|
--output-max-height-base: 276px;
|
||||||
--output-height-delta: 0px;
|
--output-height-delta: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +122,8 @@ label {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 6px 8px;
|
height: var(--control-height);
|
||||||
|
padding: 0 8px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
background: var(--input-bg);
|
background: var(--input-bg);
|
||||||
@@ -140,6 +142,49 @@ select {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.env-profile-summary {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--muted);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.env-profile-item {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.always-default-env-profile .selector-row {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.always-default-env-profile .env-profile-summary {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.always-default-env-profile:not(.custom-task-mode) .config-block {
|
||||||
|
row-gap: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.always-default-env-profile:not(.custom-task-mode) {
|
||||||
|
--output-max-height-base: 309px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.custom-task-mode .env-profile-summary {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.custom-task-mode.always-default-env-profile .selector-row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.task-row {
|
.task-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@@ -147,7 +192,7 @@ select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.task-row button {
|
.task-row button {
|
||||||
padding: 6px 15px;
|
padding: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-row .task-field {
|
.task-row .task-field {
|
||||||
@@ -254,11 +299,18 @@ button {
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 6px 10px;
|
padding: 0 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.control-btn {
|
||||||
|
height: var(--control-height);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
button:disabled {
|
button:disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|||||||
@@ -65,15 +65,29 @@
|
|||||||
<select id="profileSelect"></select>
|
<select id="profileSelect"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="env-profile-summary" id="envProfileSummary">
|
||||||
|
<div class="env-profile-item">
|
||||||
|
ENV: <span id="envSummaryValue"></span>
|
||||||
|
</div>
|
||||||
|
<div class="env-profile-item">
|
||||||
|
PROFILE: <span id="profileSummaryValue"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="task-row" id="normalTaskRow">
|
<div class="task-row" id="normalTaskRow">
|
||||||
<div class="field inline-field task-field">
|
<div class="field inline-field task-field">
|
||||||
<label for="taskSelect">Task</label>
|
<label for="taskSelect">Task</label>
|
||||||
<select id="taskSelect"></select>
|
<select id="taskSelect"></select>
|
||||||
</div>
|
</div>
|
||||||
<button id="customTaskBtn" class="ghost">Custom</button>
|
<button id="customTaskBtn" class="ghost control-btn">Custom</button>
|
||||||
<div id="taskActions">
|
<div id="taskActions">
|
||||||
<button id="runBtn" class="accent">Run</button>
|
<button id="runBtn" class="accent control-btn">Run</button>
|
||||||
<button id="abortBtn" class="ghost stop-btn hidden" disabled>Stop</button>
|
<button
|
||||||
|
id="abortBtn"
|
||||||
|
class="ghost stop-btn hidden control-btn"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
Stop
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="task-row custom-task-row hidden" id="customTaskRow">
|
<div class="task-row custom-task-row hidden" id="customTaskRow">
|
||||||
@@ -81,7 +95,7 @@
|
|||||||
<textarea id="customTaskInput" rows="2" placeholder="Enter temporary custom task..."></textarea>
|
<textarea id="customTaskInput" rows="2" placeholder="Enter temporary custom task..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-task-actions">
|
<div class="custom-task-actions">
|
||||||
<button id="normalTaskBtn" class="ghost">Normal</button>
|
<button id="normalTaskBtn" class="ghost control-btn">Normal</button>
|
||||||
<div id="taskActionsSlot"></div>
|
<div id="taskActionsSlot"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,9 +114,15 @@
|
|||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="footer-left">
|
<div class="footer-left">
|
||||||
<button id="copyRenderedBtn" class="ghost" type="button">Copy</button>
|
<button id="copyRenderedBtn" class="ghost control-btn" type="button">
|
||||||
<button id="copyRawBtn" class="ghost" type="button">Copy Markdown</button>
|
Copy
|
||||||
<button id="clearOutputBtn" class="ghost" type="button">Clear</button>
|
</button>
|
||||||
|
<button id="copyRawBtn" class="ghost control-btn" type="button">
|
||||||
|
Copy Markdown
|
||||||
|
</button>
|
||||||
|
<button id="clearOutputBtn" class="ghost control-btn" type="button">
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<button id="settingsBtn" class="link">Settings</button>
|
<button id="settingsBtn" class="link">Settings</button>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ const abortBtn = document.getElementById("abortBtn");
|
|||||||
const taskSelect = document.getElementById("taskSelect");
|
const taskSelect = document.getElementById("taskSelect");
|
||||||
const envSelect = document.getElementById("envSelect");
|
const envSelect = document.getElementById("envSelect");
|
||||||
const profileSelect = document.getElementById("profileSelect");
|
const profileSelect = document.getElementById("profileSelect");
|
||||||
|
const envProfileSummary = document.getElementById("envProfileSummary");
|
||||||
|
const envSummaryValue = document.getElementById("envSummaryValue");
|
||||||
|
const profileSummaryValue = document.getElementById("profileSummaryValue");
|
||||||
const customTaskBtn = document.getElementById("customTaskBtn");
|
const customTaskBtn = document.getElementById("customTaskBtn");
|
||||||
const normalTaskBtn = document.getElementById("normalTaskBtn");
|
const normalTaskBtn = document.getElementById("normalTaskBtn");
|
||||||
const customTaskInput = document.getElementById("customTaskInput");
|
const customTaskInput = document.getElementById("customTaskInput");
|
||||||
@@ -67,6 +70,7 @@ const state = {
|
|||||||
selectedEnvId: "",
|
selectedEnvId: "",
|
||||||
selectedProfileId: "",
|
selectedProfileId: "",
|
||||||
alwaysShowOutput: false,
|
alwaysShowOutput: false,
|
||||||
|
alwaysUseDefaultEnvProfile: false,
|
||||||
activeTabId: null,
|
activeTabId: null,
|
||||||
pendingConfigRefresh: false,
|
pendingConfigRefresh: false,
|
||||||
customTaskMode: false,
|
customTaskMode: false,
|
||||||
@@ -682,6 +686,46 @@ function resolveThemeForPopup(baseTheme) {
|
|||||||
return baseTheme || "system";
|
return baseTheme || "system";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveAppearanceToggleValue(value, fallback) {
|
||||||
|
if (value === "enabled") return true;
|
||||||
|
if (value === "disabled") return false;
|
||||||
|
if (value === "inherit" || value === null || value === undefined) {
|
||||||
|
return Boolean(fallback);
|
||||||
|
}
|
||||||
|
if (typeof value === "boolean") return value;
|
||||||
|
return Boolean(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveAlwaysUseDefaultEnvProfile(baseSetting, workspace, site) {
|
||||||
|
const resolvedBase = resolveAppearanceToggleValue(baseSetting, false);
|
||||||
|
const workspaceResolved = resolveAppearanceToggleValue(
|
||||||
|
workspace?.alwaysUseDefaultEnvProfile,
|
||||||
|
resolvedBase
|
||||||
|
);
|
||||||
|
return resolveAppearanceToggleValue(
|
||||||
|
site?.alwaysUseDefaultEnvProfile,
|
||||||
|
workspaceResolved
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateEnvProfileSummary() {
|
||||||
|
if (!envSummaryValue || !profileSummaryValue) return;
|
||||||
|
const env = getSelectedEnv();
|
||||||
|
const profile = getSelectedProfile();
|
||||||
|
envSummaryValue.textContent = env ? env.name || "Default" : "None";
|
||||||
|
profileSummaryValue.textContent = profile ? profile.name || "Default" : "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyAlwaysUseDefaultEnvProfileState() {
|
||||||
|
document.body.classList.toggle(
|
||||||
|
"always-default-env-profile",
|
||||||
|
state.alwaysUseDefaultEnvProfile
|
||||||
|
);
|
||||||
|
updateEnvSelectState();
|
||||||
|
updateProfileSelectState();
|
||||||
|
updateEnvProfileSummary();
|
||||||
|
}
|
||||||
|
|
||||||
function setAnalyzing(isAnalyzing) {
|
function setAnalyzing(isAnalyzing) {
|
||||||
state.isAnalyzing = isAnalyzing;
|
state.isAnalyzing = isAnalyzing;
|
||||||
runBtn.disabled = isAnalyzing;
|
runBtn.disabled = isAnalyzing;
|
||||||
@@ -752,6 +796,8 @@ function setCustomTaskMode(enabled, { persist = true } = {}) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
updatePromptCount();
|
updatePromptCount();
|
||||||
|
updateEnvSelectState();
|
||||||
|
updateProfileSelectState();
|
||||||
if (persist) {
|
if (persist) {
|
||||||
void persistCustomTaskState();
|
void persistCustomTaskState();
|
||||||
}
|
}
|
||||||
@@ -901,6 +947,7 @@ function renderEnvironments(envs) {
|
|||||||
option.value = "";
|
option.value = "";
|
||||||
envSelect.appendChild(option);
|
envSelect.appendChild(option);
|
||||||
updateEnvSelectState();
|
updateEnvSelectState();
|
||||||
|
updateEnvProfileSummary();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -911,6 +958,7 @@ function renderEnvironments(envs) {
|
|||||||
envSelect.appendChild(option);
|
envSelect.appendChild(option);
|
||||||
}
|
}
|
||||||
updateEnvSelectState();
|
updateEnvSelectState();
|
||||||
|
updateEnvProfileSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTaskSelectState() {
|
function updateTaskSelectState() {
|
||||||
@@ -920,7 +968,10 @@ function updateTaskSelectState() {
|
|||||||
|
|
||||||
function updateEnvSelectState() {
|
function updateEnvSelectState() {
|
||||||
const hasEnvs = state.envs.length > 0;
|
const hasEnvs = state.envs.length > 0;
|
||||||
envSelect.disabled = state.isAnalyzing || !hasEnvs;
|
envSelect.disabled =
|
||||||
|
state.isAnalyzing ||
|
||||||
|
!hasEnvs ||
|
||||||
|
(state.alwaysUseDefaultEnvProfile && !state.customTaskMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderProfiles(profiles) {
|
function renderProfiles(profiles) {
|
||||||
@@ -933,6 +984,7 @@ function renderProfiles(profiles) {
|
|||||||
option.value = "";
|
option.value = "";
|
||||||
profileSelect.appendChild(option);
|
profileSelect.appendChild(option);
|
||||||
updateProfileSelectState();
|
updateProfileSelectState();
|
||||||
|
updateEnvProfileSummary();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,11 +995,15 @@ function renderProfiles(profiles) {
|
|||||||
profileSelect.appendChild(option);
|
profileSelect.appendChild(option);
|
||||||
}
|
}
|
||||||
updateProfileSelectState();
|
updateProfileSelectState();
|
||||||
|
updateEnvProfileSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateProfileSelectState() {
|
function updateProfileSelectState() {
|
||||||
const hasProfiles = state.profiles.length > 0;
|
const hasProfiles = state.profiles.length > 0;
|
||||||
profileSelect.disabled = state.isAnalyzing || !hasProfiles;
|
profileSelect.disabled =
|
||||||
|
state.isAnalyzing ||
|
||||||
|
!hasProfiles ||
|
||||||
|
(state.alwaysUseDefaultEnvProfile && !state.customTaskMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTaskDefaultEnvId(task) {
|
function getTaskDefaultEnvId(task) {
|
||||||
@@ -968,6 +1024,7 @@ function setEnvironmentSelection(envId) {
|
|||||||
}
|
}
|
||||||
state.selectedEnvId = target;
|
state.selectedEnvId = target;
|
||||||
updatePromptCount();
|
updatePromptCount();
|
||||||
|
updateEnvProfileSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setProfileSelection(profileId) {
|
function setProfileSelection(profileId) {
|
||||||
@@ -980,6 +1037,7 @@ function setProfileSelection(profileId) {
|
|||||||
}
|
}
|
||||||
state.selectedProfileId = target;
|
state.selectedProfileId = target;
|
||||||
updatePromptCount();
|
updatePromptCount();
|
||||||
|
updateEnvProfileSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectTask(taskId, { resetEnv } = { resetEnv: false }) {
|
function selectTask(taskId, { resetEnv } = { resetEnv: false }) {
|
||||||
@@ -1105,6 +1163,7 @@ async function loadConfig() {
|
|||||||
"sites",
|
"sites",
|
||||||
"theme",
|
"theme",
|
||||||
"alwaysShowOutput",
|
"alwaysShowOutput",
|
||||||
|
"alwaysUseDefaultEnvProfile",
|
||||||
LAST_TASK_KEY,
|
LAST_TASK_KEY,
|
||||||
LAST_ENV_KEY,
|
LAST_ENV_KEY,
|
||||||
LAST_PROFILE_KEY,
|
LAST_PROFILE_KEY,
|
||||||
@@ -1156,8 +1215,14 @@ async function loadConfig() {
|
|||||||
state.globalTheme = stored.theme;
|
state.globalTheme = stored.theme;
|
||||||
}
|
}
|
||||||
state.alwaysShowOutput = Boolean(stored.alwaysShowOutput);
|
state.alwaysShowOutput = Boolean(stored.alwaysShowOutput);
|
||||||
|
state.alwaysUseDefaultEnvProfile = resolveAlwaysUseDefaultEnvProfile(
|
||||||
|
stored.alwaysUseDefaultEnvProfile,
|
||||||
|
activeWorkspace,
|
||||||
|
activeSite
|
||||||
|
);
|
||||||
applyTheme(resolveThemeForPopup(state.globalTheme));
|
applyTheme(resolveThemeForPopup(state.globalTheme));
|
||||||
updateOutputVisibility();
|
updateOutputVisibility();
|
||||||
|
applyAlwaysUseDefaultEnvProfileState();
|
||||||
state.customTaskMode = Boolean(stored[CUSTOM_TASK_MODE_KEY]);
|
state.customTaskMode = Boolean(stored[CUSTOM_TASK_MODE_KEY]);
|
||||||
state.customTaskText = stored[CUSTOM_TASK_TEXT_KEY] || "";
|
state.customTaskText = stored[CUSTOM_TASK_TEXT_KEY] || "";
|
||||||
|
|
||||||
@@ -1205,9 +1270,10 @@ async function loadConfig() {
|
|||||||
const initialTaskId = effectiveTasks.some((task) => task.id === storedTaskId)
|
const initialTaskId = effectiveTasks.some((task) => task.id === storedTaskId)
|
||||||
? storedTaskId
|
? storedTaskId
|
||||||
: effectiveTasks[0].id;
|
: effectiveTasks[0].id;
|
||||||
selectTask(initialTaskId, { resetEnv: false });
|
selectTask(initialTaskId, { resetEnv: state.alwaysUseDefaultEnvProfile });
|
||||||
|
|
||||||
const task = effectiveTasks.find((item) => item.id === initialTaskId);
|
const task = effectiveTasks.find((item) => item.id === initialTaskId);
|
||||||
|
if (!state.alwaysUseDefaultEnvProfile) {
|
||||||
if (storedEnvId && effectiveEnvs.some((env) => env.id === storedEnvId)) {
|
if (storedEnvId && effectiveEnvs.some((env) => env.id === storedEnvId)) {
|
||||||
setEnvironmentSelection(storedEnvId);
|
setEnvironmentSelection(storedEnvId);
|
||||||
} else {
|
} else {
|
||||||
@@ -1222,6 +1288,7 @@ async function loadConfig() {
|
|||||||
} else {
|
} else {
|
||||||
setProfileSelection(getTaskDefaultProfileId(task));
|
setProfileSelection(getTaskDefaultProfileId(task));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
storedTaskId !== state.selectedTaskId ||
|
storedTaskId !== state.selectedTaskId ||
|
||||||
@@ -1296,6 +1363,10 @@ async function handleAnalyze() {
|
|||||||
setStatus("Select a task.");
|
setStatus("Select a task.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (state.alwaysUseDefaultEnvProfile && !forcedTask && !state.customTaskMode) {
|
||||||
|
setEnvironmentSelection(getTaskDefaultEnvId(task));
|
||||||
|
setProfileSelection(getTaskDefaultProfileId(task));
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
apiKeys = [],
|
apiKeys = [],
|
||||||
@@ -1751,7 +1822,13 @@ async function loadShortcutRunRequest() {
|
|||||||
await persistSelections();
|
await persistSelections();
|
||||||
state.autoRunPending = false;
|
state.autoRunPending = false;
|
||||||
state.shortcutRunPending = false;
|
state.shortcutRunPending = false;
|
||||||
void handleExtractAndAnalyze();
|
void handleExtractAndAnalyze().finally(() => {
|
||||||
|
if (!state.alwaysUseDefaultEnvProfile) return;
|
||||||
|
const selectedTask = getSelectedTask();
|
||||||
|
if (!selectedTask) return;
|
||||||
|
setEnvironmentSelection(getTaskDefaultEnvId(selectedTask));
|
||||||
|
setProfileSelection(getTaskDefaultProfileId(selectedTask));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadAutoRunRequest() {
|
async function loadAutoRunRequest() {
|
||||||
@@ -1819,7 +1896,8 @@ chrome.storage.onChanged.addListener((changes) => {
|
|||||||
"workspaces",
|
"workspaces",
|
||||||
"sites",
|
"sites",
|
||||||
"theme",
|
"theme",
|
||||||
"alwaysShowOutput"
|
"alwaysShowOutput",
|
||||||
|
"alwaysUseDefaultEnvProfile"
|
||||||
];
|
];
|
||||||
if (configKeys.some((key) => changes[key])) {
|
if (configKeys.some((key) => changes[key])) {
|
||||||
scheduleConfigRefresh();
|
scheduleConfigRefresh();
|
||||||
|
|||||||
@@ -749,6 +749,10 @@ button:active {
|
|||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-fields.four {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
.inline-fields .field {
|
.inline-fields .field {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="inline-fields two appearance-fields">
|
<div class="inline-fields four appearance-fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="themeSelect">Theme</label>
|
<label for="themeSelect">Theme</label>
|
||||||
<select id="themeSelect">
|
<select id="themeSelect">
|
||||||
@@ -122,6 +122,22 @@
|
|||||||
<option value="bottom-center">Bottom Center</option>
|
<option value="bottom-center">Bottom Center</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="alwaysUseDefaultEnvProfileSelect">
|
||||||
|
Always use default ENV/PROFILE
|
||||||
|
</label>
|
||||||
|
<select id="alwaysUseDefaultEnvProfileSelect">
|
||||||
|
<option value="enabled">Enabled</option>
|
||||||
|
<option value="disabled">Disabled</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label for="emptyToolbarBehaviorSelect">Empty toolbar</label>
|
||||||
|
<select id="emptyToolbarBehaviorSelect">
|
||||||
|
<option value="hide">Hide Toolbar</option>
|
||||||
|
<option value="open">Show "Open SiteCompanion"</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-fields two appearance-toggles">
|
<div class="inline-fields two appearance-toggles">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|||||||
@@ -19,8 +19,14 @@ const statusSidebarEl = document.getElementById("statusSidebar");
|
|||||||
const sidebarErrorsEl = document.getElementById("sidebarErrors");
|
const sidebarErrorsEl = document.getElementById("sidebarErrors");
|
||||||
const themeSelect = document.getElementById("themeSelect");
|
const themeSelect = document.getElementById("themeSelect");
|
||||||
const toolbarPositionSelect = document.getElementById("toolbarPositionSelect");
|
const toolbarPositionSelect = document.getElementById("toolbarPositionSelect");
|
||||||
|
const emptyToolbarBehaviorSelect = document.getElementById(
|
||||||
|
"emptyToolbarBehaviorSelect"
|
||||||
|
);
|
||||||
const toolbarAutoHide = document.getElementById("toolbarAutoHide");
|
const toolbarAutoHide = document.getElementById("toolbarAutoHide");
|
||||||
const alwaysShowOutput = document.getElementById("alwaysShowOutput");
|
const alwaysShowOutput = document.getElementById("alwaysShowOutput");
|
||||||
|
const alwaysUseDefaultEnvProfileSelect = document.getElementById(
|
||||||
|
"alwaysUseDefaultEnvProfileSelect"
|
||||||
|
);
|
||||||
const globalSitesContainer = document.getElementById("globalSites");
|
const globalSitesContainer = document.getElementById("globalSites");
|
||||||
const toc = document.querySelector(".toc");
|
const toc = document.querySelector(".toc");
|
||||||
const tocResizer = document.getElementById("tocResizer");
|
const tocResizer = document.getElementById("tocResizer");
|
||||||
@@ -453,8 +459,14 @@ function buildSettingsSnapshot() {
|
|||||||
toolbarPosition: toolbarPositionSelect
|
toolbarPosition: toolbarPositionSelect
|
||||||
? toolbarPositionSelect.value
|
? toolbarPositionSelect.value
|
||||||
: "bottom-right",
|
: "bottom-right",
|
||||||
|
emptyToolbarBehavior: emptyToolbarBehaviorSelect
|
||||||
|
? emptyToolbarBehaviorSelect.value
|
||||||
|
: "open",
|
||||||
toolbarAutoHide: toolbarAutoHide ? toolbarAutoHide.checked : true,
|
toolbarAutoHide: toolbarAutoHide ? toolbarAutoHide.checked : true,
|
||||||
alwaysShowOutput: alwaysShowOutput ? alwaysShowOutput.checked : false
|
alwaysShowOutput: alwaysShowOutput ? alwaysShowOutput.checked : false,
|
||||||
|
alwaysUseDefaultEnvProfile: alwaysUseDefaultEnvProfileSelect
|
||||||
|
? alwaysUseDefaultEnvProfileSelect.value === "enabled"
|
||||||
|
: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2287,6 +2299,10 @@ function collectWorkspaces() {
|
|||||||
const nameInput = card.querySelector(".workspace-name");
|
const nameInput = card.querySelector(".workspace-name");
|
||||||
const themeSelect = card.querySelector(".appearance-theme");
|
const themeSelect = card.querySelector(".appearance-theme");
|
||||||
const toolbarSelect = card.querySelector(".appearance-toolbar-position");
|
const toolbarSelect = card.querySelector(".appearance-toolbar-position");
|
||||||
|
const defaultEnvProfileSelect = card.querySelector(
|
||||||
|
".appearance-default-env-profile"
|
||||||
|
);
|
||||||
|
const emptyToolbarSelect = card.querySelector(".appearance-empty-toolbar");
|
||||||
|
|
||||||
// Collect nested resources
|
// Collect nested resources
|
||||||
const envsContainer = card.querySelector(".workspace-envs");
|
const envsContainer = card.querySelector(".workspace-envs");
|
||||||
@@ -2310,6 +2326,12 @@ function collectWorkspaces() {
|
|||||||
name: (nameInput?.value || "Untitled Workspace").trim(),
|
name: (nameInput?.value || "Untitled Workspace").trim(),
|
||||||
theme: themeSelect?.value || "inherit",
|
theme: themeSelect?.value || "inherit",
|
||||||
toolbarPosition: toolbarSelect?.value || "inherit",
|
toolbarPosition: toolbarSelect?.value || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
defaultEnvProfileSelect?.value
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
emptyToolbarSelect?.value
|
||||||
|
),
|
||||||
envConfigs: envsContainer ? collectEnvConfigs(envsContainer) : [],
|
envConfigs: envsContainer ? collectEnvConfigs(envsContainer) : [],
|
||||||
profiles: profilesContainer ? collectProfiles(profilesContainer) : [],
|
profiles: profilesContainer ? collectProfiles(profilesContainer) : [],
|
||||||
tasks: tasksContainer ? collectTasks(tasksContainer) : [],
|
tasks: tasksContainer ? collectTasks(tasksContainer) : [],
|
||||||
@@ -2426,8 +2448,192 @@ function renderWorkspaceSection(title, containerClass, items, builder, newItemFa
|
|||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const THEME_LABELS = {
|
||||||
|
system: "System",
|
||||||
|
light: "Light",
|
||||||
|
dark: "Dark"
|
||||||
|
};
|
||||||
|
|
||||||
|
const TOOLBAR_POSITION_LABELS = {
|
||||||
|
"bottom-right": "Bottom Right",
|
||||||
|
"bottom-left": "Bottom Left",
|
||||||
|
"top-right": "Top Right",
|
||||||
|
"top-left": "Top Left",
|
||||||
|
"bottom-center": "Bottom Center"
|
||||||
|
};
|
||||||
|
|
||||||
|
const EMPTY_TOOLBAR_BEHAVIOR_LABELS = {
|
||||||
|
hide: "Hide Toolbar",
|
||||||
|
open: 'Show "Open SiteCompanion"'
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalizeAppearanceToggle(value) {
|
||||||
|
if (value === "inherit" || value === "enabled" || value === "disabled") {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (value === true) return "enabled";
|
||||||
|
if (value === false) return "disabled";
|
||||||
|
return "inherit";
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeEmptyToolbarBehavior(value, allowInherit = true) {
|
||||||
|
if (value === "hide" || value === "open") return value;
|
||||||
|
if (allowInherit && value === "inherit") return "inherit";
|
||||||
|
return allowInherit ? "inherit" : "open";
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveAppearanceToggleValue(value, fallback) {
|
||||||
|
const normalized = normalizeAppearanceToggle(value);
|
||||||
|
if (normalized === "inherit") return Boolean(fallback);
|
||||||
|
return normalized === "enabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getThemeLabel(value) {
|
||||||
|
return THEME_LABELS[value] || String(value || "System");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToolbarPositionLabel(value) {
|
||||||
|
return TOOLBAR_POSITION_LABELS[value] || String(value || "Bottom Right");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultEnvProfileLabel(value) {
|
||||||
|
return value ? "Enabled" : "Disabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEmptyToolbarBehaviorLabel(value) {
|
||||||
|
return EMPTY_TOOLBAR_BEHAVIOR_LABELS[value] || "Hide Toolbar";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGlobalAppearanceConfig() {
|
||||||
|
return {
|
||||||
|
theme: themeSelect?.value || "system",
|
||||||
|
toolbarPosition: toolbarPositionSelect?.value || "bottom-right",
|
||||||
|
alwaysUseDefaultEnvProfile: resolveAppearanceToggleValue(
|
||||||
|
alwaysUseDefaultEnvProfileSelect?.value,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
emptyToolbarBehaviorSelect?.value,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAppearanceInheritedHint(selectEl, hintEl, label) {
|
||||||
|
if (!selectEl || !hintEl) return;
|
||||||
|
if (selectEl.value !== "inherit") {
|
||||||
|
hintEl.textContent = "Not inheriting";
|
||||||
|
hintEl.classList.remove("hidden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hintEl.textContent = `Inherited: ${label}`;
|
||||||
|
hintEl.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAppearanceInheritanceIndicators() {
|
||||||
|
const global = getGlobalAppearanceConfig();
|
||||||
|
const workspaceCards = document.querySelectorAll(".workspace-card");
|
||||||
|
const workspaceAppearance = new Map();
|
||||||
|
|
||||||
|
workspaceCards.forEach((card) => {
|
||||||
|
const themeSelect = card.querySelector(".appearance-theme");
|
||||||
|
const toolbarSelect = card.querySelector(".appearance-toolbar-position");
|
||||||
|
const defaultSelect = card.querySelector(".appearance-default-env-profile");
|
||||||
|
const emptyToolbarSelect = card.querySelector(".appearance-empty-toolbar");
|
||||||
|
const themeValue = themeSelect?.value || "inherit";
|
||||||
|
const toolbarValue = toolbarSelect?.value || "inherit";
|
||||||
|
const defaultValue = defaultSelect?.value || "inherit";
|
||||||
|
const emptyToolbarValue = normalizeEmptyToolbarBehavior(
|
||||||
|
emptyToolbarSelect?.value || "inherit"
|
||||||
|
);
|
||||||
|
const resolvedTheme =
|
||||||
|
themeValue === "inherit" ? global.theme : themeValue;
|
||||||
|
const resolvedToolbar =
|
||||||
|
toolbarValue === "inherit" ? global.toolbarPosition : toolbarValue;
|
||||||
|
const resolvedDefault = resolveAppearanceToggleValue(
|
||||||
|
defaultValue,
|
||||||
|
global.alwaysUseDefaultEnvProfile
|
||||||
|
);
|
||||||
|
const resolvedEmptyToolbar =
|
||||||
|
emptyToolbarValue === "inherit"
|
||||||
|
? global.emptyToolbarBehavior
|
||||||
|
: emptyToolbarValue;
|
||||||
|
workspaceAppearance.set(card.dataset.id, {
|
||||||
|
theme: resolvedTheme,
|
||||||
|
toolbarPosition: resolvedToolbar,
|
||||||
|
alwaysUseDefaultEnvProfile: resolvedDefault,
|
||||||
|
emptyToolbarBehavior: resolvedEmptyToolbar
|
||||||
|
});
|
||||||
|
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
themeSelect,
|
||||||
|
card.querySelector('.appearance-inherited[data-appearance-key="theme"]'),
|
||||||
|
getThemeLabel(global.theme)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
toolbarSelect,
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="toolbarPosition"]'
|
||||||
|
),
|
||||||
|
getToolbarPositionLabel(global.toolbarPosition)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
defaultSelect,
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="alwaysUseDefaultEnvProfile"]'
|
||||||
|
),
|
||||||
|
getDefaultEnvProfileLabel(global.alwaysUseDefaultEnvProfile)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
emptyToolbarSelect,
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="emptyToolbarBehavior"]'
|
||||||
|
),
|
||||||
|
getEmptyToolbarBehaviorLabel(global.emptyToolbarBehavior)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const siteCards = document.querySelectorAll(".site-card");
|
||||||
|
siteCards.forEach((card) => {
|
||||||
|
const workspaceId = card.querySelector(".site-workspace")?.value || "global";
|
||||||
|
const resolved =
|
||||||
|
workspaceAppearance.get(workspaceId) || global;
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
card.querySelector(".appearance-theme"),
|
||||||
|
card.querySelector('.appearance-inherited[data-appearance-key="theme"]'),
|
||||||
|
getThemeLabel(resolved.theme)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
card.querySelector(".appearance-toolbar-position"),
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="toolbarPosition"]'
|
||||||
|
),
|
||||||
|
getToolbarPositionLabel(resolved.toolbarPosition)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
card.querySelector(".appearance-default-env-profile"),
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="alwaysUseDefaultEnvProfile"]'
|
||||||
|
),
|
||||||
|
getDefaultEnvProfileLabel(resolved.alwaysUseDefaultEnvProfile)
|
||||||
|
);
|
||||||
|
updateAppearanceInheritedHint(
|
||||||
|
card.querySelector(".appearance-empty-toolbar"),
|
||||||
|
card.querySelector(
|
||||||
|
'.appearance-inherited[data-appearance-key="emptyToolbarBehavior"]'
|
||||||
|
),
|
||||||
|
getEmptyToolbarBehaviorLabel(resolved.emptyToolbarBehavior)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function buildAppearanceSection(
|
function buildAppearanceSection(
|
||||||
{ theme = "inherit", toolbarPosition = "inherit" } = {},
|
{
|
||||||
|
theme = "inherit",
|
||||||
|
toolbarPosition = "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile = "inherit",
|
||||||
|
emptyToolbarBehavior = "inherit"
|
||||||
|
} = {},
|
||||||
{ stateKey } = {}
|
{ stateKey } = {}
|
||||||
) {
|
) {
|
||||||
const details = document.createElement("details");
|
const details = document.createElement("details");
|
||||||
@@ -2475,6 +2681,10 @@ function buildAppearanceSection(
|
|||||||
themeSelect.value = theme || "inherit";
|
themeSelect.value = theme || "inherit";
|
||||||
themeField.appendChild(themeLabel);
|
themeField.appendChild(themeLabel);
|
||||||
themeField.appendChild(themeSelect);
|
themeField.appendChild(themeSelect);
|
||||||
|
const themeHint = document.createElement("div");
|
||||||
|
themeHint.className = "hint appearance-inherited hidden";
|
||||||
|
themeHint.dataset.appearanceKey = "theme";
|
||||||
|
themeField.appendChild(themeHint);
|
||||||
|
|
||||||
const toolbarField = document.createElement("div");
|
const toolbarField = document.createElement("div");
|
||||||
toolbarField.className = "field";
|
toolbarField.className = "field";
|
||||||
@@ -2507,11 +2717,69 @@ function buildAppearanceSection(
|
|||||||
toolbarSelect.value = toolbarPosition || "inherit";
|
toolbarSelect.value = toolbarPosition || "inherit";
|
||||||
toolbarField.appendChild(toolbarLabel);
|
toolbarField.appendChild(toolbarLabel);
|
||||||
toolbarField.appendChild(toolbarSelect);
|
toolbarField.appendChild(toolbarSelect);
|
||||||
|
const toolbarHint = document.createElement("div");
|
||||||
|
toolbarHint.className = "hint appearance-inherited hidden";
|
||||||
|
toolbarHint.dataset.appearanceKey = "toolbarPosition";
|
||||||
|
toolbarField.appendChild(toolbarHint);
|
||||||
|
|
||||||
|
const defaultField = document.createElement("div");
|
||||||
|
defaultField.className = "field";
|
||||||
|
const defaultLabel = document.createElement("label");
|
||||||
|
defaultLabel.textContent = "Always use default ENV/PROFILE";
|
||||||
|
const defaultSelect = document.createElement("select");
|
||||||
|
defaultSelect.className = "appearance-default-env-profile";
|
||||||
|
const defaultOptions = [
|
||||||
|
{ value: "inherit", label: "Inherit" },
|
||||||
|
{ value: "enabled", label: "Enabled" },
|
||||||
|
{ value: "disabled", label: "Disabled" }
|
||||||
|
];
|
||||||
|
for (const optValue of defaultOptions) {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = optValue.value;
|
||||||
|
opt.textContent = optValue.label;
|
||||||
|
defaultSelect.appendChild(opt);
|
||||||
|
}
|
||||||
|
defaultSelect.value = normalizeAppearanceToggle(alwaysUseDefaultEnvProfile);
|
||||||
|
defaultField.appendChild(defaultLabel);
|
||||||
|
defaultField.appendChild(defaultSelect);
|
||||||
|
const defaultHint = document.createElement("div");
|
||||||
|
defaultHint.className = "hint appearance-inherited hidden";
|
||||||
|
defaultHint.dataset.appearanceKey = "alwaysUseDefaultEnvProfile";
|
||||||
|
defaultField.appendChild(defaultHint);
|
||||||
|
|
||||||
|
const emptyToolbarField = document.createElement("div");
|
||||||
|
emptyToolbarField.className = "field";
|
||||||
|
const emptyToolbarLabel = document.createElement("label");
|
||||||
|
emptyToolbarLabel.textContent = "Empty toolbar";
|
||||||
|
const emptyToolbarSelect = document.createElement("select");
|
||||||
|
emptyToolbarSelect.className = "appearance-empty-toolbar";
|
||||||
|
const emptyToolbarOptions = [
|
||||||
|
{ value: "inherit", label: "Inherit" },
|
||||||
|
{ value: "hide", label: "Hide Toolbar" },
|
||||||
|
{ value: "open", label: 'Show "Open SiteCompanion"' }
|
||||||
|
];
|
||||||
|
for (const optionConfig of emptyToolbarOptions) {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.value = optionConfig.value;
|
||||||
|
opt.textContent = optionConfig.label;
|
||||||
|
emptyToolbarSelect.appendChild(opt);
|
||||||
|
}
|
||||||
|
emptyToolbarSelect.value = normalizeEmptyToolbarBehavior(
|
||||||
|
emptyToolbarBehavior
|
||||||
|
);
|
||||||
|
emptyToolbarField.appendChild(emptyToolbarLabel);
|
||||||
|
emptyToolbarField.appendChild(emptyToolbarSelect);
|
||||||
|
const emptyToolbarHint = document.createElement("div");
|
||||||
|
emptyToolbarHint.className = "hint appearance-inherited hidden";
|
||||||
|
emptyToolbarHint.dataset.appearanceKey = "emptyToolbarBehavior";
|
||||||
|
emptyToolbarField.appendChild(emptyToolbarHint);
|
||||||
|
|
||||||
const appearanceRow = document.createElement("div");
|
const appearanceRow = document.createElement("div");
|
||||||
appearanceRow.className = "inline-fields two appearance-fields";
|
appearanceRow.className = "inline-fields four appearance-fields";
|
||||||
appearanceRow.appendChild(themeField);
|
appearanceRow.appendChild(themeField);
|
||||||
appearanceRow.appendChild(toolbarField);
|
appearanceRow.appendChild(toolbarField);
|
||||||
|
appearanceRow.appendChild(defaultField);
|
||||||
|
appearanceRow.appendChild(emptyToolbarField);
|
||||||
body.appendChild(appearanceRow);
|
body.appendChild(appearanceRow);
|
||||||
details.appendChild(body);
|
details.appendChild(body);
|
||||||
registerDetail(details, details.open);
|
registerDetail(details, details.open);
|
||||||
@@ -4024,6 +4292,7 @@ function buildWorkspaceCard(ws, allWorkspaces = [], allSites = []) {
|
|||||||
if (confirm(`Delete workspace "${ws.name}"? All items will move to global.`)) {
|
if (confirm(`Delete workspace "${ws.name}"? All items will move to global.`)) {
|
||||||
card.remove();
|
card.remove();
|
||||||
scheduleSidebarErrors();
|
scheduleSidebarErrors();
|
||||||
|
updateAppearanceInheritanceIndicators();
|
||||||
updateToc(collectWorkspaces(), collectSites());
|
updateToc(collectWorkspaces(), collectSites());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -4034,7 +4303,13 @@ function buildWorkspaceCard(ws, allWorkspaces = [], allSites = []) {
|
|||||||
const appearanceSection = buildAppearanceSection(
|
const appearanceSection = buildAppearanceSection(
|
||||||
{
|
{
|
||||||
theme: ws.theme || "inherit",
|
theme: ws.theme || "inherit",
|
||||||
toolbarPosition: ws.toolbarPosition || "inherit"
|
toolbarPosition: ws.toolbarPosition || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
ws.alwaysUseDefaultEnvProfile
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
ws.emptyToolbarBehavior
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{ stateKey: `workspace:${card.dataset.id}:appearance` }
|
{ stateKey: `workspace:${card.dataset.id}:appearance` }
|
||||||
);
|
);
|
||||||
@@ -4255,6 +4530,10 @@ function collectSites() {
|
|||||||
const parsedTarget = parseExtractionTargetInput(extractInput?.value || "");
|
const parsedTarget = parseExtractionTargetInput(extractInput?.value || "");
|
||||||
const themeSelect = card.querySelector(".appearance-theme");
|
const themeSelect = card.querySelector(".appearance-theme");
|
||||||
const toolbarSelect = card.querySelector(".appearance-toolbar-position");
|
const toolbarSelect = card.querySelector(".appearance-toolbar-position");
|
||||||
|
const defaultEnvProfileSelect = card.querySelector(
|
||||||
|
".appearance-default-env-profile"
|
||||||
|
);
|
||||||
|
const emptyToolbarSelect = card.querySelector(".appearance-empty-toolbar");
|
||||||
const envsContainer = card.querySelector(".site-envs");
|
const envsContainer = card.querySelector(".site-envs");
|
||||||
const profilesContainer = card.querySelector(".site-profiles");
|
const profilesContainer = card.querySelector(".site-profiles");
|
||||||
const tasksContainer = card.querySelector(".site-tasks");
|
const tasksContainer = card.querySelector(".site-tasks");
|
||||||
@@ -4272,6 +4551,12 @@ function collectSites() {
|
|||||||
extractTarget: parsedTarget.target,
|
extractTarget: parsedTarget.target,
|
||||||
theme: themeSelect?.value || "inherit",
|
theme: themeSelect?.value || "inherit",
|
||||||
toolbarPosition: toolbarSelect?.value || "inherit",
|
toolbarPosition: toolbarSelect?.value || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
defaultEnvProfileSelect?.value
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
emptyToolbarSelect?.value
|
||||||
|
),
|
||||||
envConfigs: envsContainer ? collectEnvConfigs(envsContainer) : [],
|
envConfigs: envsContainer ? collectEnvConfigs(envsContainer) : [],
|
||||||
profiles: profilesContainer ? collectProfiles(profilesContainer) : [],
|
profiles: profilesContainer ? collectProfiles(profilesContainer) : [],
|
||||||
tasks: tasksContainer ? collectTasks(tasksContainer) : [],
|
tasks: tasksContainer ? collectTasks(tasksContainer) : [],
|
||||||
@@ -4421,7 +4706,13 @@ function buildSiteCard(site, allWorkspaces = []) {
|
|||||||
const appearanceSection = buildAppearanceSection(
|
const appearanceSection = buildAppearanceSection(
|
||||||
{
|
{
|
||||||
theme: site.theme || "inherit",
|
theme: site.theme || "inherit",
|
||||||
toolbarPosition: site.toolbarPosition || "inherit"
|
toolbarPosition: site.toolbarPosition || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
site.alwaysUseDefaultEnvProfile
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
site.emptyToolbarBehavior
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{ stateKey: `site:${card.dataset.id}:appearance` }
|
{ stateKey: `site:${card.dataset.id}:appearance` }
|
||||||
);
|
);
|
||||||
@@ -5388,6 +5679,8 @@ async function loadSettings() {
|
|||||||
toolbarPosition = "bottom-right",
|
toolbarPosition = "bottom-right",
|
||||||
toolbarAutoHide: storedToolbarAutoHide = true,
|
toolbarAutoHide: storedToolbarAutoHide = true,
|
||||||
alwaysShowOutput: storedAlwaysShowOutput = false,
|
alwaysShowOutput: storedAlwaysShowOutput = false,
|
||||||
|
alwaysUseDefaultEnvProfile: storedAlwaysUseDefaultEnvProfile = false,
|
||||||
|
emptyToolbarBehavior: storedEmptyToolbarBehavior = "open",
|
||||||
sidebarWidth
|
sidebarWidth
|
||||||
} = await getStorage([
|
} = await getStorage([
|
||||||
"apiKey",
|
"apiKey",
|
||||||
@@ -5410,6 +5703,8 @@ async function loadSettings() {
|
|||||||
"sites",
|
"sites",
|
||||||
"toolbarPosition",
|
"toolbarPosition",
|
||||||
"toolbarAutoHide",
|
"toolbarAutoHide",
|
||||||
|
"emptyToolbarBehavior",
|
||||||
|
"alwaysUseDefaultEnvProfile",
|
||||||
SIDEBAR_WIDTH_KEY
|
SIDEBAR_WIDTH_KEY
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -5422,9 +5717,22 @@ async function loadSettings() {
|
|||||||
if (toolbarAutoHide) {
|
if (toolbarAutoHide) {
|
||||||
toolbarAutoHide.checked = Boolean(storedToolbarAutoHide);
|
toolbarAutoHide.checked = Boolean(storedToolbarAutoHide);
|
||||||
}
|
}
|
||||||
|
if (emptyToolbarBehaviorSelect) {
|
||||||
|
emptyToolbarBehaviorSelect.value = normalizeEmptyToolbarBehavior(
|
||||||
|
storedEmptyToolbarBehavior,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
if (alwaysShowOutput) {
|
if (alwaysShowOutput) {
|
||||||
alwaysShowOutput.checked = Boolean(storedAlwaysShowOutput);
|
alwaysShowOutput.checked = Boolean(storedAlwaysShowOutput);
|
||||||
}
|
}
|
||||||
|
if (alwaysUseDefaultEnvProfileSelect) {
|
||||||
|
const normalizedDefault = normalizeAppearanceToggle(
|
||||||
|
storedAlwaysUseDefaultEnvProfile
|
||||||
|
);
|
||||||
|
alwaysUseDefaultEnvProfileSelect.value =
|
||||||
|
normalizedDefault === "enabled" ? "enabled" : "disabled";
|
||||||
|
}
|
||||||
if (Number.isFinite(sidebarWidth)) {
|
if (Number.isFinite(sidebarWidth)) {
|
||||||
applySidebarWidth(sidebarWidth);
|
applySidebarWidth(sidebarWidth);
|
||||||
}
|
}
|
||||||
@@ -5460,6 +5768,12 @@ async function loadSettings() {
|
|||||||
...workspace,
|
...workspace,
|
||||||
theme: workspace.theme || "inherit",
|
theme: workspace.theme || "inherit",
|
||||||
toolbarPosition: workspace.toolbarPosition || "inherit",
|
toolbarPosition: workspace.toolbarPosition || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
workspace.alwaysUseDefaultEnvProfile
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
workspace.emptyToolbarBehavior
|
||||||
|
),
|
||||||
envConfigs: normalizeConfigList(workspace.envConfigs),
|
envConfigs: normalizeConfigList(workspace.envConfigs),
|
||||||
profiles: normalizeConfigList(workspace.profiles),
|
profiles: normalizeConfigList(workspace.profiles),
|
||||||
tasks: normalizeConfigList(workspace.tasks),
|
tasks: normalizeConfigList(workspace.tasks),
|
||||||
@@ -5484,6 +5798,12 @@ async function loadSettings() {
|
|||||||
extractTarget: normalizedTarget.target,
|
extractTarget: normalizedTarget.target,
|
||||||
theme: site.theme || "inherit",
|
theme: site.theme || "inherit",
|
||||||
toolbarPosition: site.toolbarPosition || "inherit",
|
toolbarPosition: site.toolbarPosition || "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: normalizeAppearanceToggle(
|
||||||
|
site.alwaysUseDefaultEnvProfile
|
||||||
|
),
|
||||||
|
emptyToolbarBehavior: normalizeEmptyToolbarBehavior(
|
||||||
|
site.emptyToolbarBehavior
|
||||||
|
),
|
||||||
envConfigs: normalizeConfigList(site.envConfigs),
|
envConfigs: normalizeConfigList(site.envConfigs),
|
||||||
profiles: normalizeConfigList(site.profiles),
|
profiles: normalizeConfigList(site.profiles),
|
||||||
tasks: normalizeConfigList(site.tasks),
|
tasks: normalizeConfigList(site.tasks),
|
||||||
@@ -5785,6 +6105,7 @@ async function loadSettings() {
|
|||||||
updateSidebarErrors();
|
updateSidebarErrors();
|
||||||
updateToc(workspaces, sites);
|
updateToc(workspaces, sites);
|
||||||
renderGlobalSitesList(sites);
|
renderGlobalSitesList(sites);
|
||||||
|
updateAppearanceInheritanceIndicators();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveSettings() {
|
async function saveSettings() {
|
||||||
@@ -5913,8 +6234,14 @@ async function saveSettings() {
|
|||||||
toolbarPosition: toolbarPositionSelect
|
toolbarPosition: toolbarPositionSelect
|
||||||
? toolbarPositionSelect.value
|
? toolbarPositionSelect.value
|
||||||
: "bottom-right",
|
: "bottom-right",
|
||||||
|
emptyToolbarBehavior: emptyToolbarBehaviorSelect
|
||||||
|
? emptyToolbarBehaviorSelect.value
|
||||||
|
: "open",
|
||||||
toolbarAutoHide: toolbarAutoHide ? toolbarAutoHide.checked : true,
|
toolbarAutoHide: toolbarAutoHide ? toolbarAutoHide.checked : true,
|
||||||
alwaysShowOutput: alwaysShowOutput ? alwaysShowOutput.checked : false,
|
alwaysShowOutput: alwaysShowOutput ? alwaysShowOutput.checked : false,
|
||||||
|
alwaysUseDefaultEnvProfile: alwaysUseDefaultEnvProfileSelect
|
||||||
|
? alwaysUseDefaultEnvProfileSelect.value === "enabled"
|
||||||
|
: false,
|
||||||
workspaces: updatedWorkspaces,
|
workspaces: updatedWorkspaces,
|
||||||
sites: mergedSites
|
sites: mergedSites
|
||||||
});
|
});
|
||||||
@@ -6059,6 +6386,8 @@ addWorkspaceBtn.addEventListener("click", () => {
|
|||||||
name: "New Workspace",
|
name: "New Workspace",
|
||||||
theme: "inherit",
|
theme: "inherit",
|
||||||
toolbarPosition: "inherit",
|
toolbarPosition: "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: "inherit",
|
||||||
|
emptyToolbarBehavior: "inherit",
|
||||||
envConfigs: [],
|
envConfigs: [],
|
||||||
profiles: [],
|
profiles: [],
|
||||||
tasks: [],
|
tasks: [],
|
||||||
@@ -6075,6 +6404,7 @@ addWorkspaceBtn.addEventListener("click", () => {
|
|||||||
centerCardInView(newCard);
|
centerCardInView(newCard);
|
||||||
refreshWorkspaceInheritedLists();
|
refreshWorkspaceInheritedLists();
|
||||||
scheduleSidebarErrors();
|
scheduleSidebarErrors();
|
||||||
|
updateAppearanceInheritanceIndicators();
|
||||||
updateToc(collectWorkspaces(), collectSites());
|
updateToc(collectWorkspaces(), collectSites());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -6087,6 +6417,8 @@ addSiteBtn.addEventListener("click", () => {
|
|||||||
workspaceId: "global",
|
workspaceId: "global",
|
||||||
theme: "inherit",
|
theme: "inherit",
|
||||||
toolbarPosition: "inherit",
|
toolbarPosition: "inherit",
|
||||||
|
alwaysUseDefaultEnvProfile: "inherit",
|
||||||
|
emptyToolbarBehavior: "inherit",
|
||||||
envConfigs: [],
|
envConfigs: [],
|
||||||
profiles: [],
|
profiles: [],
|
||||||
tasks: [],
|
tasks: [],
|
||||||
@@ -6103,6 +6435,7 @@ addSiteBtn.addEventListener("click", () => {
|
|||||||
centerCardInView(newCard);
|
centerCardInView(newCard);
|
||||||
refreshSiteInheritedLists();
|
refreshSiteInheritedLists();
|
||||||
scheduleSidebarErrors();
|
scheduleSidebarErrors();
|
||||||
|
updateAppearanceInheritanceIndicators();
|
||||||
updateToc(collectWorkspaces(), collectSites());
|
updateToc(collectWorkspaces(), collectSites());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -6609,6 +6942,7 @@ function handleSettingsInputChange() {
|
|||||||
scheduleSidebarErrors();
|
scheduleSidebarErrors();
|
||||||
scheduleDirtyCheck();
|
scheduleDirtyCheck();
|
||||||
refreshInheritedSourceLabels();
|
refreshInheritedSourceLabels();
|
||||||
|
updateAppearanceInheritanceIndicators();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("input", handleSettingsInputChange);
|
document.addEventListener("input", handleSettingsInputChange);
|
||||||
|
|||||||
Reference in New Issue
Block a user