mirror of
https://github.com/eondrcode/obsidian-manager.git
synced 2026-07-22 11:40:24 +00:00
chore: 1.0.6
This commit is contained in:
parent
450bad9c65
commit
e9b11020da
15 changed files with 1011 additions and 346 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "better-plugins-manager",
|
||||
"name": "Better Plugins Manager",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"minAppVersion": "1.5.8",
|
||||
"description": "Plugin Manager: Simplify, Enhance, Personalize | 插件管理器:简化操作、增强功能、个性化设置",
|
||||
"author": "zero",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-sample-plugin",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
@ -21,4 +21,4 @@
|
|||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ export interface Tag {
|
|||
// 已知的特殊 Tag
|
||||
export const BPM_TAG_ID = "bpm-install"; // BPM 安装标识
|
||||
export const BPM_IGNORE_TAG = "bpm-ignore"; // BPM 忽略标识
|
||||
export const EONDR_PLUGIN_TAG_ID = "bpm-eondr-plugin"; // Eondr 自有插件标识
|
||||
|
||||
export interface Delay {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Notice, normalizePath, requestUrl } from "obsidian";
|
||||
import type { PluginManifest, RequestUrlResponse } from "obsidian";
|
||||
import Manager from "main";
|
||||
import type { ManagerPlugin } from "./data/types";
|
||||
import { BPM_TAG_ID } from "./repo-resolver";
|
||||
|
||||
/**
|
||||
|
|
@ -260,10 +261,11 @@ const upsertInstalledPluginRecord = (
|
|||
plugin.desc = nextDesc || plugin.desc;
|
||||
plugin.enabled = true;
|
||||
if (shouldHaveBpmTag && !plugin.tags.includes(BPM_TAG_ID)) plugin.tags.push(BPM_TAG_ID);
|
||||
manager.applySpecialPluginTags(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
manager.settings.Plugins.push({
|
||||
const record: ManagerPlugin = {
|
||||
id: pluginId,
|
||||
name: nextName,
|
||||
desc: nextDesc,
|
||||
|
|
@ -272,7 +274,9 @@ const upsertInstalledPluginRecord = (
|
|||
enabled: true,
|
||||
delay: "",
|
||||
note: "",
|
||||
});
|
||||
};
|
||||
manager.applySpecialPluginTags(record);
|
||||
manager.settings.Plugins.push(record);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ export default {
|
|||
设置_基础设置_淡化插件_描述: 'Provide a visual fade effect for disabled plugins to clearly distinguish between enabled and disabled plugins.',
|
||||
设置_基础设置_隐藏BPM标签_标题: 'Hide Preset Tags (Install/Ignore)',
|
||||
设置_基础设置_隐藏BPM标签_描述: 'Hides automatically added bpm-install and bpm-ignore tags from the list.',
|
||||
设置_基础设置_边栏编排_标题: 'Enable ribbon order',
|
||||
设置_基础设置_边栏编排_描述: 'When enabled, BPM controls Ribbon icon order and visibility. When disabled, BPM removes its overrides and uses Obsidian native order.',
|
||||
设置_基础设置_启动检查更新_标题: 'Check updates on startup',
|
||||
设置_基础设置_启动检查更新_描述: 'When BPM opens, automatically check for plugin updates and briefly show the count.',
|
||||
设置_基础设置_来源启动检查更新_标题: 'Check source updates on startup',
|
||||
|
|
@ -274,6 +276,7 @@ export default {
|
|||
|
||||
命令_管理面板_描述: 'Open the plugin manager',
|
||||
标签_BPM安装_名称: 'bpm install',
|
||||
标签_Eondr插件_名称: 'Eondr plugin',
|
||||
管理器_下载更新_描述: 'Download an update (choose version, incl. pre-release)',
|
||||
安装_成功_提示: 'Installed/updated: {name}',
|
||||
安装_错误_限速: 'GitHub rate-limited (403). Please set a GitHub token and retry.',
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ export default {
|
|||
|
||||
设置_基础设置_隐藏BPM标签_标题: '隐藏 BPM 预设标签(安装/忽略)',
|
||||
设置_基础设置_隐藏BPM标签_描述: '开启后列表不显示自动添加的 BPM 安装和 BPM 忽略标签。',
|
||||
设置_基础设置_边栏编排_标题: '启用边栏编排',
|
||||
设置_基础设置_边栏编排_描述: '开启后 BPM 接管 Ribbon 图标的排序和显隐;关闭后移除接管,使用 Obsidian 原生边栏顺序。',
|
||||
设置_基础设置_启动检查更新_标题: '启动时检测插件更新',
|
||||
设置_基础设置_启动检查更新_描述: '打开 BPM 时自动检测可更新插件,并在右上角提示数量。',
|
||||
设置_基础设置_来源启动检查更新_标题: '启动时检测来源更新',
|
||||
|
|
@ -233,6 +235,7 @@ export default {
|
|||
设置_基础设置_分组命令_标题: '分组控制插件命令',
|
||||
设置_基础设置_分组命令_描述: '启用此选项可以一键启用或禁用指定分组中的所有插件。(重启Obsidian生效)',
|
||||
标签_BPM安装_名称: 'BPM 安装',
|
||||
标签_Eondr插件_名称: 'Eondr 出品',
|
||||
|
||||
设置_主页面功能_标题: '主页面功能',
|
||||
设置_主页面功能_描述: '选择插件管理页中每个插件功能是直接展示在 item 上,还是收纳在右键菜单里。',
|
||||
|
|
|
|||
373
src/main.ts
373
src/main.ts
|
|
@ -7,7 +7,7 @@ import Commands from './command';
|
|||
import Agreement from 'src/agreement';
|
||||
import { RepoResolver, ensureBpmTagExists, BPM_TAG_ID } from './repo-resolver';
|
||||
import { Notice, Platform, requestUrl } from 'obsidian';
|
||||
import { BetaSource, ManagerPlugin, BPM_IGNORE_TAG } from './data/types';
|
||||
import { BetaSource, ManagerPlugin, BPM_IGNORE_TAG, EONDR_PLUGIN_TAG_ID } from './data/types';
|
||||
import { runMigrations } from './migrations';
|
||||
import { fetchReleaseVersions, installPluginFromGithub, installThemeFromGithub, ReleaseVersion, sanitizeRepo } from './github-install';
|
||||
import { performSelfCheck } from './self-check';
|
||||
|
|
@ -15,7 +15,7 @@ import { SystemRibbonManager } from './manager/system-ribbon-manager';
|
|||
import { RibbonItem } from './data/types';
|
||||
|
||||
type UpdateSource = 'official' | 'github' | 'unknown';
|
||||
interface UpdateStatus {
|
||||
interface UpdateStatus {
|
||||
source: UpdateSource;
|
||||
localVersion?: string;
|
||||
remoteVersion?: string | null;
|
||||
|
|
@ -25,7 +25,12 @@ interface UpdateStatus {
|
|||
checkedAt?: number;
|
||||
repo?: string | null;
|
||||
versions?: ReleaseVersion[];
|
||||
}
|
||||
}
|
||||
|
||||
const EONDR_PLUGIN_RULES = [
|
||||
{ id: "i18n", repo: "eondrcode/obsidian-i18n" },
|
||||
];
|
||||
const EONDR_REPO_OWNER = "eondrcode";
|
||||
|
||||
export default class Manager extends Plugin {
|
||||
public settings: ManagerSettings;
|
||||
|
|
@ -38,7 +43,7 @@ export default class Manager extends Plugin {
|
|||
|
||||
public agreement: Agreement;
|
||||
public repoResolver: RepoResolver;
|
||||
public systemRibbonManager: SystemRibbonManager;
|
||||
public systemRibbonManager?: SystemRibbonManager;
|
||||
public updateStatus: Record<string, UpdateStatus> = {};
|
||||
private updateProgressNotice: Notice | null = null;
|
||||
|
||||
|
|
@ -62,36 +67,41 @@ export default class Manager extends Plugin {
|
|||
this.settings.LANGUAGE_INITIALIZED = true;
|
||||
await this.saveSettings();
|
||||
}
|
||||
// 初始化语言系统
|
||||
this.translator = new Translator(this);
|
||||
let builtinTagsChanged = false;
|
||||
const tagCountBeforeBpmEnsure = this.settings.TAGS.length;
|
||||
ensureBpmTagExists(this);
|
||||
builtinTagsChanged = this.settings.TAGS.length !== tagCountBeforeBpmEnsure;
|
||||
this.ensureBpmTagAndRecords();
|
||||
this.ensureSelfPluginRecord();
|
||||
|
||||
// 确保 BPM Ignore 标签存在
|
||||
if (!this.settings.TAGS.some(t => t.id === BPM_IGNORE_TAG)) {
|
||||
this.settings.TAGS.push({
|
||||
// 初始化语言系统
|
||||
this.translator = new Translator(this);
|
||||
let builtinTagsChanged = false;
|
||||
const tagCountBeforeBpmEnsure = this.settings.TAGS.length;
|
||||
ensureBpmTagExists(this);
|
||||
builtinTagsChanged = this.settings.TAGS.length !== tagCountBeforeBpmEnsure;
|
||||
|
||||
// 确保 BPM Ignore 标签存在
|
||||
if (!this.settings.TAGS.some(t => t.id === BPM_IGNORE_TAG)) {
|
||||
this.settings.TAGS.push({
|
||||
id: BPM_IGNORE_TAG,
|
||||
name: this.translator.t("标签_BPM忽略_名称") || "BPM Ignored",
|
||||
color: "#6c757d" // 灰色
|
||||
});
|
||||
builtinTagsChanged = true;
|
||||
}
|
||||
if (this.normalizeBuiltinTagNames() || builtinTagsChanged) await this.saveSettings();
|
||||
});
|
||||
builtinTagsChanged = true;
|
||||
}
|
||||
if (!this.settings.TAGS.some(t => t.id === EONDR_PLUGIN_TAG_ID)) {
|
||||
this.settings.TAGS.push({
|
||||
id: EONDR_PLUGIN_TAG_ID,
|
||||
name: this.translator.t("标签_Eondr插件_名称") || "Eondr Plugin",
|
||||
color: "#B36BFF",
|
||||
});
|
||||
builtinTagsChanged = true;
|
||||
}
|
||||
this.ensureBpmTagAndRecords();
|
||||
this.ensureSelfPluginRecord();
|
||||
if (this.normalizeBuiltinTagNames() || builtinTagsChanged) await this.saveSettings();
|
||||
|
||||
this.repoResolver = new RepoResolver(this);
|
||||
|
||||
// 初始化 Ribbon 管理器。功能编排不写入 Obsidian workspace 配置,只用 BPM 数据驱动运行时样式。
|
||||
this.systemRibbonManager = new SystemRibbonManager(this.app, this);
|
||||
const savedRibbonItems = [...(this.settings.RIBBON_SETTINGS || [])]
|
||||
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
||||
const orderedRibbonIds = savedRibbonItems.map((item) => item.id);
|
||||
const hiddenRibbonStatus: Record<string, boolean> = {};
|
||||
savedRibbonItems.forEach((item) => hiddenRibbonStatus[item.id] = !item.visible);
|
||||
await this.syncRibbonConfig(orderedRibbonIds, hiddenRibbonStatus);
|
||||
if (this.isRibbonManagerEnabled()) {
|
||||
await this.syncStoredRibbonConfig();
|
||||
} else {
|
||||
this.clearRibbonStyleOverrides();
|
||||
}
|
||||
|
||||
// 初始化侧边栏图标
|
||||
this.addRibbonIcon('folder-cog', this.translator.t('通用_管理器_文本'), () => { this.managerModal = new ManagerModal(this.app, this); this.managerModal.open(); });
|
||||
|
|
@ -111,53 +121,50 @@ export default class Manager extends Plugin {
|
|||
await this.agreement.parsePluginGithub(params);
|
||||
});
|
||||
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
this.updateRibbonStyles();
|
||||
if (Platform.isMobile) {
|
||||
this.setupMenuObserver();
|
||||
} else {
|
||||
// 仅桌面端启用“拖出即隐藏”功能
|
||||
this.setupDragToHideObserver();
|
||||
}
|
||||
// 延迟启动自检,确保 Obsidian 初始化完成,避免自动接管被覆盖
|
||||
setTimeout(() => {
|
||||
this.cleanRibbonItems(); // 启动后清理一次
|
||||
if (this.settings.DELAY) performSelfCheck(this);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
public async onunload() {
|
||||
if (this.dragObserverCleanup) {
|
||||
this.dragObserverCleanup();
|
||||
this.dragObserverCleanup = null;
|
||||
}
|
||||
|
||||
if (this.settings.DELAY) this.disableDelaysForAllPlugins();
|
||||
if (this.menuObserver) {
|
||||
this.menuObserver.disconnect();
|
||||
}
|
||||
|
||||
// 临走前再清理一次
|
||||
this.cleanRibbonItems();
|
||||
|
||||
this.systemRibbonManager?.stopWatch();
|
||||
}
|
||||
|
||||
private setupDragToHideObserver() {
|
||||
const handlePointerDown = (e: PointerEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
// 检查是否是 Ribbon Icon
|
||||
if (target && target.closest && target.closest('.side-dock-ribbon-action')) {
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
this.startRibbonRuntimeFeatures();
|
||||
// 延迟启动自检,确保 Obsidian 初始化完成,避免自动接管被覆盖
|
||||
setTimeout(() => {
|
||||
if (this.isRibbonManagerEnabled()) this.cleanRibbonItems(); // 启动后清理一次
|
||||
if (this.settings.DELAY) performSelfCheck(this);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
public async onunload() {
|
||||
this.stopRibbonRuntimeFeatures();
|
||||
|
||||
if (this.settings.DELAY) this.disableDelaysForAllPlugins();
|
||||
|
||||
// 临走前再清理一次
|
||||
if (this.isRibbonManagerEnabled()) this.cleanRibbonItems();
|
||||
|
||||
this.systemRibbonManager?.stopWatch();
|
||||
this.clearRibbonStyleOverrides();
|
||||
}
|
||||
|
||||
private setupDragToHideObserver() {
|
||||
if (!this.isRibbonManagerEnabled() || this.dragObserverCleanup) return;
|
||||
|
||||
const handlePointerDown = (e: PointerEvent) => {
|
||||
if (!this.isRibbonManagerEnabled()) return;
|
||||
const target = e.target as HTMLElement;
|
||||
// 检查是否是 Ribbon Icon
|
||||
if (target && target.closest && target.closest('.side-dock-ribbon-action')) {
|
||||
this.isRibbonDragging = true;
|
||||
this.draggedRibbonItem = target.closest('.side-dock-ribbon-action') as HTMLElement;
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerUp = async (e: PointerEvent) => {
|
||||
if (!this.isRibbonDragging || !this.draggedRibbonItem) {
|
||||
this.isRibbonDragging = false;
|
||||
this.draggedRibbonItem = null;
|
||||
|
||||
const handlePointerUp = async (e: PointerEvent) => {
|
||||
if (!this.isRibbonManagerEnabled()) {
|
||||
this.isRibbonDragging = false;
|
||||
this.draggedRibbonItem = null;
|
||||
return;
|
||||
}
|
||||
if (!this.isRibbonDragging || !this.draggedRibbonItem) {
|
||||
this.isRibbonDragging = false;
|
||||
this.draggedRibbonItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -201,11 +208,13 @@ export default class Manager extends Plugin {
|
|||
document.removeEventListener('pointerdown', handlePointerDown, true);
|
||||
document.removeEventListener('pointerup', handlePointerUp, true);
|
||||
};
|
||||
}
|
||||
|
||||
private async hideRibbonItemByLabel(label: string) {
|
||||
// 查找对应的 Item ID
|
||||
const items = this.settings.RIBBON_SETTINGS;
|
||||
}
|
||||
|
||||
private async hideRibbonItemByLabel(label: string) {
|
||||
if (!this.isRibbonManagerEnabled()) return;
|
||||
|
||||
// 查找对应的 Item ID
|
||||
const items = this.settings.RIBBON_SETTINGS;
|
||||
const targetItem = items.find(i => i.name === label); // name 通常就是 label
|
||||
|
||||
let targetId = targetItem?.id;
|
||||
|
|
@ -250,10 +259,88 @@ export default class Manager extends Plugin {
|
|||
this.updateRibbonStyles();
|
||||
|
||||
new Notice(this.translator.t("Ribbon_已隐藏_通知", { name: label }));
|
||||
}
|
||||
}
|
||||
|
||||
public async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); }
|
||||
}
|
||||
}
|
||||
|
||||
public isRibbonManagerEnabled(): boolean {
|
||||
return this.settings?.RIBBON_MANAGER_ENABLED !== false;
|
||||
}
|
||||
|
||||
private ensureSystemRibbonManager() {
|
||||
if (!this.systemRibbonManager) this.systemRibbonManager = new SystemRibbonManager(this.app, this);
|
||||
}
|
||||
|
||||
private clearRibbonStyleOverrides() {
|
||||
document.getElementById("bpm-ribbon-manager-style")?.remove();
|
||||
}
|
||||
|
||||
private stopRibbonRuntimeFeatures() {
|
||||
if (this.dragObserverCleanup) {
|
||||
this.dragObserverCleanup();
|
||||
this.dragObserverCleanup = null;
|
||||
}
|
||||
this.isRibbonDragging = false;
|
||||
this.draggedRibbonItem = null;
|
||||
|
||||
if (this.menuObserver) {
|
||||
this.menuObserver.disconnect();
|
||||
this.menuObserver = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async syncStoredRibbonConfig() {
|
||||
if (!this.isRibbonManagerEnabled()) return;
|
||||
this.ensureSystemRibbonManager();
|
||||
const savedRibbonItems = [...(this.settings.RIBBON_SETTINGS || [])]
|
||||
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
||||
const orderedRibbonIds = savedRibbonItems.map((item) => item.id);
|
||||
const hiddenRibbonStatus: Record<string, boolean> = {};
|
||||
savedRibbonItems.forEach((item) => hiddenRibbonStatus[item.id] = !item.visible);
|
||||
await this.syncRibbonConfig(orderedRibbonIds, hiddenRibbonStatus);
|
||||
}
|
||||
|
||||
private startRibbonRuntimeFeatures() {
|
||||
if (!this.isRibbonManagerEnabled()) {
|
||||
this.stopRibbonRuntimeFeatures();
|
||||
this.clearRibbonStyleOverrides();
|
||||
return;
|
||||
}
|
||||
|
||||
this.ensureSystemRibbonManager();
|
||||
this.updateRibbonStyles();
|
||||
if (Platform.isMobile) {
|
||||
this.setupMenuObserver();
|
||||
} else {
|
||||
// 仅桌面端启用“拖出即隐藏”功能
|
||||
this.setupDragToHideObserver();
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshRibbonManagerFeature() {
|
||||
if (this.isRibbonManagerEnabled()) {
|
||||
await this.syncStoredRibbonConfig();
|
||||
this.startRibbonRuntimeFeatures();
|
||||
} else {
|
||||
this.stopRibbonRuntimeFeatures();
|
||||
this.systemRibbonManager?.stopWatch();
|
||||
this.systemRibbonManager = undefined;
|
||||
this.clearRibbonStyleOverrides();
|
||||
try {
|
||||
this.ribbonModal?.close?.();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
this.ribbonModal = null;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.managerModal?.refreshRibbonFeatureAvailability?.();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); }
|
||||
public async saveSettings() { await this.saveData(this.settings); }
|
||||
|
||||
// 保存单个插件配置。保留方法名以兼容旧调用点。
|
||||
|
|
@ -434,14 +521,32 @@ export default class Manager extends Plugin {
|
|||
await this.saveSettings();
|
||||
}
|
||||
|
||||
public ensureBpmTagAndRecords() {
|
||||
ensureBpmTagExists(this);
|
||||
// 确保 BPM 安装的插件拥有标签
|
||||
this.settings.BPM_INSTALLED.forEach((id) => {
|
||||
const mp = this.settings.Plugins.find(p => p.id === id);
|
||||
if (mp && !mp.tags.includes(BPM_TAG_ID)) mp.tags.push(BPM_TAG_ID);
|
||||
});
|
||||
}
|
||||
public ensureBpmTagAndRecords() {
|
||||
ensureBpmTagExists(this);
|
||||
// 确保 BPM 安装的插件拥有标签
|
||||
this.settings.BPM_INSTALLED.forEach((id) => {
|
||||
const mp = this.settings.Plugins.find(p => p.id === id);
|
||||
if (mp && !mp.tags.includes(BPM_TAG_ID)) mp.tags.push(BPM_TAG_ID);
|
||||
});
|
||||
this.settings.Plugins.forEach((plugin) => this.applySpecialPluginTags(plugin));
|
||||
}
|
||||
|
||||
private isEondrPlugin(pluginId: string): boolean {
|
||||
const normalizedId = pluginId.trim().toLowerCase();
|
||||
if (EONDR_PLUGIN_RULES.some((rule) => rule.id.toLowerCase() === normalizedId)) return true;
|
||||
|
||||
const mappedRepo = sanitizeRepo(this.settings.REPO_MAP?.[pluginId] || "").toLowerCase();
|
||||
return Boolean(mappedRepo && (
|
||||
mappedRepo.startsWith(`${EONDR_REPO_OWNER}/`)
|
||||
|| EONDR_PLUGIN_RULES.some((rule) => rule.repo.toLowerCase() === mappedRepo)
|
||||
));
|
||||
}
|
||||
|
||||
public applySpecialPluginTags(plugin: ManagerPlugin) {
|
||||
if (this.isEondrPlugin(plugin.id) && !plugin.tags.includes(EONDR_PLUGIN_TAG_ID)) {
|
||||
plugin.tags.push(EONDR_PLUGIN_TAG_ID);
|
||||
}
|
||||
}
|
||||
|
||||
private normalizeBuiltinTagNames(): boolean {
|
||||
let changed = false;
|
||||
|
|
@ -464,12 +569,17 @@ export default class Manager extends Plugin {
|
|||
"BPM Install",
|
||||
"BPM Installed",
|
||||
], "#409EFF");
|
||||
normalize(BPM_IGNORE_TAG, this.translator.t("标签_BPM忽略_名称") || "BPM 忽略", [
|
||||
"BPM Ignore",
|
||||
"BPM Ignored",
|
||||
], "#6c757d");
|
||||
return changed;
|
||||
}
|
||||
normalize(BPM_IGNORE_TAG, this.translator.t("标签_BPM忽略_名称") || "BPM 忽略", [
|
||||
"BPM Ignore",
|
||||
"BPM Ignored",
|
||||
], "#6c757d");
|
||||
normalize(EONDR_PLUGIN_TAG_ID, this.translator.t("标签_Eondr插件_名称") || "Eondr 出品", [
|
||||
"Eondr Plugin",
|
||||
"Eondr Plugins",
|
||||
"Eondr",
|
||||
], "#B36BFF");
|
||||
return changed;
|
||||
}
|
||||
|
||||
// 确保 BPM 自身也存在于插件记录中(用于面板显示)
|
||||
public ensureSelfPluginRecord() {
|
||||
|
|
@ -632,10 +742,11 @@ export default class Manager extends Plugin {
|
|||
nextPlugins.push(mp);
|
||||
pluginSettingsById.set(p1Item.id, mp);
|
||||
}
|
||||
if (bpmInstalledIds.has(p1Item.id) && !mp.tags.includes(BPM_TAG_ID)) {
|
||||
mp.tags.push(BPM_TAG_ID);
|
||||
}
|
||||
});
|
||||
if (bpmInstalledIds.has(p1Item.id) && !mp.tags.includes(BPM_TAG_ID)) {
|
||||
mp.tags.push(BPM_TAG_ID);
|
||||
}
|
||||
this.applySpecialPluginTags(mp);
|
||||
});
|
||||
this.settings.Plugins = nextPlugins;
|
||||
// BPM 自身保持启用且不允许延迟
|
||||
this.ensureSelfPluginRecord();
|
||||
|
|
@ -980,11 +1091,15 @@ export default class Manager extends Plugin {
|
|||
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`;
|
||||
}
|
||||
|
||||
public updateRibbonStyles() {
|
||||
if (!this.settings) return;
|
||||
|
||||
let styleEl = document.getElementById("bpm-ribbon-manager-style");
|
||||
if (!styleEl) {
|
||||
public updateRibbonStyles() {
|
||||
if (!this.settings) return;
|
||||
if (!this.isRibbonManagerEnabled()) {
|
||||
this.clearRibbonStyleOverrides();
|
||||
return;
|
||||
}
|
||||
|
||||
let styleEl = document.getElementById("bpm-ribbon-manager-style");
|
||||
if (!styleEl) {
|
||||
styleEl = document.createElement("style");
|
||||
styleEl.id = "bpm-ribbon-manager-style";
|
||||
document.head.appendChild(styleEl);
|
||||
|
|
@ -1035,12 +1150,15 @@ export default class Manager extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
private menuObserver: MutationObserver | null = null;
|
||||
|
||||
setupMenuObserver() {
|
||||
this.menuObserver = new MutationObserver((mutations) => {
|
||||
let shouldProcess = false;
|
||||
let targetNode: HTMLElement | null = null;
|
||||
private menuObserver: MutationObserver | null = null;
|
||||
|
||||
setupMenuObserver() {
|
||||
if (!this.isRibbonManagerEnabled() || this.menuObserver) return;
|
||||
|
||||
this.menuObserver = new MutationObserver((mutations) => {
|
||||
if (!this.isRibbonManagerEnabled()) return;
|
||||
let shouldProcess = false;
|
||||
let targetNode: HTMLElement | null = null;
|
||||
|
||||
for (const mutation of mutations) {
|
||||
if (mutation.addedNodes.length > 0) {
|
||||
|
|
@ -1072,11 +1190,13 @@ export default class Manager extends Plugin {
|
|||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
|
||||
processMenuItems(menuScrollElement: HTMLElement) {
|
||||
// [修复] 移动端 Obsidian 菜单项包裹在 .menu-group 中
|
||||
// 必须在 .menu-group 内排序,否则会破坏样式布局
|
||||
}
|
||||
|
||||
processMenuItems(menuScrollElement: HTMLElement) {
|
||||
if (!this.isRibbonManagerEnabled()) return;
|
||||
|
||||
// [修复] 移动端 Obsidian 菜单项包裹在 .menu-group 中
|
||||
// 必须在 .menu-group 内排序,否则会破坏样式布局
|
||||
let containerElement: HTMLElement = menuScrollElement;
|
||||
const menuGroup = menuScrollElement.querySelector(".menu-group");
|
||||
if (menuGroup) {
|
||||
|
|
@ -1157,14 +1277,23 @@ export default class Manager extends Plugin {
|
|||
|
||||
|
||||
|
||||
// 功能编排只应用运行时样式,不写入 Obsidian workspace 配置或 Ribbon 内存状态。
|
||||
applyRibbonConfigToMemory(orderedIds: string[], hiddenStatus: Record<string, boolean>) {
|
||||
this.updateRibbonStyles();
|
||||
}
|
||||
|
||||
public async syncRibbonConfig(orderedIds: string[], hiddenStatus: Record<string, boolean>) {
|
||||
// 更新本地设置以匹配原生配置
|
||||
const currentItems = this.settings.RIBBON_SETTINGS || [];
|
||||
// 功能编排只应用运行时样式,不写入 Obsidian workspace 配置或 Ribbon 内存状态。
|
||||
applyRibbonConfigToMemory(orderedIds: string[], hiddenStatus: Record<string, boolean>) {
|
||||
if (!this.isRibbonManagerEnabled()) {
|
||||
this.clearRibbonStyleOverrides();
|
||||
return;
|
||||
}
|
||||
this.updateRibbonStyles();
|
||||
}
|
||||
|
||||
public async syncRibbonConfig(orderedIds: string[], hiddenStatus: Record<string, boolean>) {
|
||||
if (!this.isRibbonManagerEnabled()) {
|
||||
this.clearRibbonStyleOverrides();
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新本地设置以匹配原生配置
|
||||
const currentItems = this.settings.RIBBON_SETTINGS || [];
|
||||
const itemMap = new Map(currentItems.map(i => [i.id, i]));
|
||||
|
||||
const newItems: RibbonItem[] = [];
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,11 @@ export class RibbonModal extends Modal {
|
|||
}
|
||||
|
||||
async onOpen() {
|
||||
if (!this.manager.isRibbonManagerEnabled()) {
|
||||
this.close();
|
||||
return;
|
||||
}
|
||||
|
||||
this.manager.ribbonModal = this;
|
||||
this.modalEl.addClass("ribbon-manager-modal");
|
||||
this.titleEl.setText(this.manager.translator.t("Ribbon_标题"));
|
||||
|
|
@ -33,6 +38,8 @@ export class RibbonModal extends Modal {
|
|||
|
||||
// 同步 Ribbon 项:读取当前工作区的 Ribbon,合并到设置中
|
||||
async syncRibbonItems() {
|
||||
if (!this.manager.isRibbonManagerEnabled()) return;
|
||||
|
||||
// 以 BPM 自己的 data.json 为源头,只从运行时内存补齐新出现的 Ribbon 项。
|
||||
const savedItems = [...(this.manager.settings.RIBBON_SETTINGS || [])]
|
||||
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
||||
|
|
@ -76,6 +83,7 @@ export class RibbonModal extends Modal {
|
|||
this.renderRootEl = contentEl;
|
||||
this.renderToolbarInRoot = showToolbar;
|
||||
contentEl.empty();
|
||||
if (!this.manager.isRibbonManagerEnabled()) return;
|
||||
|
||||
if (showToolbar) this.renderToolbar(contentEl);
|
||||
this.renderDraggableList(contentEl);
|
||||
|
|
@ -283,6 +291,8 @@ export class RibbonModal extends Modal {
|
|||
}
|
||||
|
||||
async moveItem(oldIndex: number, newIndex: number) {
|
||||
if (!this.manager.isRibbonManagerEnabled()) return;
|
||||
|
||||
const items = this.manager.settings.RIBBON_SETTINGS;
|
||||
if (oldIndex < 0 || oldIndex >= items.length || newIndex < 0 || newIndex > items.length) {
|
||||
this.display();
|
||||
|
|
@ -297,6 +307,8 @@ export class RibbonModal extends Modal {
|
|||
}
|
||||
|
||||
private async persistRibbonConfig() {
|
||||
if (!this.manager.isRibbonManagerEnabled()) return;
|
||||
|
||||
const items = this.manager.settings.RIBBON_SETTINGS;
|
||||
items.forEach((item, idx) => item.order = idx);
|
||||
await this.manager.saveSettings();
|
||||
|
|
@ -311,6 +323,8 @@ export class RibbonModal extends Modal {
|
|||
}
|
||||
|
||||
async resetRibbonLayout() {
|
||||
if (!this.manager.isRibbonManagerEnabled()) return;
|
||||
|
||||
const items = this.manager.settings.RIBBON_SETTINGS;
|
||||
items.sort((a, b) => (a.name || a.id).localeCompare(b.name || b.id));
|
||||
items.forEach((item, idx) => {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ export interface ManagerSettings {
|
|||
DELAY: boolean;
|
||||
/** 是否在插件卡片中隐藏 BPM 内置标签,例如 BPM 管理标识和 BPM 忽略。 */
|
||||
HIDE_BPM_TAG: boolean;
|
||||
/** 是否启用边栏编排接管;关闭时 BPM 不再排序或隐藏 Ribbon 图标。 */
|
||||
RIBBON_MANAGER_ENABLED: boolean;
|
||||
/** 管理页插件功能显示位置;item 表示直接展示在插件卡片上,menu 表示收纳到右键菜单。 */
|
||||
MAIN_PAGE_ACTION_PLACEMENT: MainPageActionPlacementSettings;
|
||||
/** 自检发现非 BPM 管理插件时,是否自动接管 community-plugins.json。 */
|
||||
|
|
@ -81,15 +83,19 @@ export interface ManagerSettings {
|
|||
/** 持久化的搜索关键词,仅在 PERSISTENCE 开启时作为管理页默认搜索值。 */
|
||||
FILTER_SEARCH: string;
|
||||
FILTER_STATUS: string;
|
||||
FILTER_STATUS_VALUES?: string[];
|
||||
FILTER_STATUS_OPERATOR: FilterOperator;
|
||||
/** 持久化的分组筛选 id,仅在 PERSISTENCE 开启时生效。 */
|
||||
FILTER_GROUP: string;
|
||||
FILTER_GROUP_VALUES?: string[];
|
||||
FILTER_GROUP_OPERATOR: FilterOperator;
|
||||
/** 持久化的标签筛选 id,仅在 PERSISTENCE 开启时生效。 */
|
||||
FILTER_TAG: string;
|
||||
FILTER_TAG_VALUES?: string[];
|
||||
FILTER_TAG_OPERATOR: FilterOperator;
|
||||
/** 持久化的延迟配置筛选 id,仅在 PERSISTENCE 与 DELAY 开启时生效。 */
|
||||
FILTER_DELAY: string;
|
||||
FILTER_DELAY_VALUES?: string[];
|
||||
FILTER_DELAY_OPERATOR: FilterOperator;
|
||||
|
||||
// 样式设置页
|
||||
|
|
@ -161,6 +167,7 @@ export const DEFAULT_SETTINGS: ManagerSettings = {
|
|||
CENTER: false,
|
||||
DELAY: false,
|
||||
HIDE_BPM_TAG: false,
|
||||
RIBBON_MANAGER_ENABLED: false,
|
||||
MAIN_PAGE_ACTION_PLACEMENT: { ...DEFAULT_MAIN_PAGE_ACTION_PLACEMENT },
|
||||
AUTO_TAKEOVER: false,
|
||||
SELF_CHECK_IGNORED: false,
|
||||
|
|
@ -174,12 +181,16 @@ export const DEFAULT_SETTINGS: ManagerSettings = {
|
|||
// 管理页筛选状态
|
||||
FILTER_SEARCH: "",
|
||||
FILTER_STATUS: "all",
|
||||
FILTER_STATUS_VALUES: [],
|
||||
FILTER_STATUS_OPERATOR: "contains",
|
||||
FILTER_GROUP: "",
|
||||
FILTER_GROUP_VALUES: [],
|
||||
FILTER_GROUP_OPERATOR: "contains",
|
||||
FILTER_TAG: "",
|
||||
FILTER_TAG_VALUES: [],
|
||||
FILTER_TAG_OPERATOR: "contains",
|
||||
FILTER_DELAY: "",
|
||||
FILTER_DELAY_VALUES: [],
|
||||
FILTER_DELAY_OPERATOR: "contains",
|
||||
|
||||
// 样式设置页
|
||||
|
|
|
|||
|
|
@ -35,7 +35,14 @@ export default class ManagerBasis extends BaseSetting {
|
|||
const persistenceToggle = new ToggleComponent(persistenceBar.controlEl);
|
||||
persistenceToggle.setValue(this.settings.PERSISTENCE);
|
||||
persistenceToggle.onChange((value) => {
|
||||
const managerModal = this.manager.managerModal;
|
||||
if (value) {
|
||||
managerModal?.persistCurrentFilters();
|
||||
}
|
||||
this.settings.PERSISTENCE = value;
|
||||
if (!value && managerModal) {
|
||||
managerModal.usePersistedFiltersAsSessionFilters();
|
||||
}
|
||||
this.manager.saveSettings();
|
||||
});
|
||||
|
||||
|
|
@ -111,6 +118,17 @@ export default class ManagerBasis extends BaseSetting {
|
|||
this.manager.managerModal?.reloadShowData();
|
||||
});
|
||||
|
||||
const ribbonManagerBar = new Setting(this.containerEl)
|
||||
.setName(this.manager.translator.t('设置_基础设置_边栏编排_标题'))
|
||||
.setDesc(this.manager.translator.t('设置_基础设置_边栏编排_描述'));
|
||||
const ribbonManagerToggle = new ToggleComponent(ribbonManagerBar.controlEl);
|
||||
ribbonManagerToggle.setValue(this.settings.RIBBON_MANAGER_ENABLED !== false);
|
||||
ribbonManagerToggle.onChange(async (value) => {
|
||||
this.settings.RIBBON_MANAGER_ENABLED = value;
|
||||
await this.manager.saveSettings();
|
||||
await this.manager.refreshRibbonManagerFeature();
|
||||
});
|
||||
|
||||
heading('设置_基础设置_分组_命令');
|
||||
|
||||
const CommandItemBar = new Setting(this.containerEl)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import BaseSetting from "../base-setting";
|
||||
import { Notice, setIcon, Setting } from "obsidian";
|
||||
import { BPM_TAG_ID } from "src/repo-resolver";
|
||||
import { BPM_IGNORE_TAG } from "src/data/types";
|
||||
import { BPM_IGNORE_TAG, EONDR_PLUGIN_TAG_ID } from "src/data/types";
|
||||
import Commands from "src/command";
|
||||
|
||||
export default class ManagerTag extends BaseSetting {
|
||||
|
|
@ -10,7 +10,7 @@ export default class ManagerTag extends BaseSetting {
|
|||
}
|
||||
|
||||
private isPresetTag(tagId: string): boolean {
|
||||
return tagId === BPM_TAG_ID || tagId === BPM_IGNORE_TAG;
|
||||
return tagId === BPM_TAG_ID || tagId === BPM_IGNORE_TAG || tagId === EONDR_PLUGIN_TAG_ID;
|
||||
}
|
||||
|
||||
main(): void {
|
||||
|
|
@ -77,7 +77,7 @@ export default class ManagerTag extends BaseSetting {
|
|||
const nextId = id.trim();
|
||||
const nextName = name.trim() || nextId;
|
||||
const containsId = this.manager.settings.TAGS.some(tag => tag.id === nextId);
|
||||
if (!containsId && nextId !== '' && nextId !== BPM_TAG_ID && nextId !== BPM_IGNORE_TAG) {
|
||||
if (!containsId && nextId !== '' && !this.isPresetTag(nextId)) {
|
||||
if (color === '') color = this.manager.generateAutoColor(this.manager.settings.TAGS.map(t => t.color));
|
||||
this.manager.settings.TAGS.push({ id: nextId, name: nextName, color });
|
||||
this.manager.saveSettings();
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export class TroubleshootPanel {
|
|||
startBtn.setButtonText(this.t("排查_开始_按钮"));
|
||||
startBtn.setCta();
|
||||
startBtn.setDisabled(enabledPlugins.length === 0);
|
||||
startBtn.onClick(async () => {
|
||||
startBtn.onClick(async () => {
|
||||
await this.startTroubleshoot();
|
||||
});
|
||||
|
||||
|
|
|
|||
234
styles.css
234
styles.css
|
|
@ -1894,15 +1894,16 @@ body.theme-dark {
|
|||
}
|
||||
|
||||
/* 筛选面板展开动画 */
|
||||
.manager-container--mobile .bpm-mobile-header__filters {
|
||||
transition: max-height 0.25s ease, opacity 0.2s ease, padding 0.25s ease, margin 0.25s ease;
|
||||
overflow: hidden;
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters.is-collapsed {
|
||||
max-height: 0 !important;
|
||||
.manager-container--mobile .bpm-mobile-header__filters {
|
||||
transition: max-height 0.25s ease, opacity 0.2s ease, padding 0.25s ease, margin 0.25s ease;
|
||||
overflow: visible;
|
||||
max-height: 500px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters.is-collapsed {
|
||||
overflow: hidden;
|
||||
max-height: 0 !important;
|
||||
opacity: 0 !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
|
|
@ -2602,17 +2603,25 @@ body.theme-dark {
|
|||
}
|
||||
|
||||
.manager-filter-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
height: 34px;
|
||||
border: 1px solid var(--bpm-border);
|
||||
border-radius: var(--bpm-radius-sm);
|
||||
background: var(--bpm-surface);
|
||||
overflow: hidden;
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.manager-filter-field:has(.manager-multiselect-filter) {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.manager-filter-field:has(.manager-multiselect-filter.is-open) {
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
.manager-filter-field--select {
|
||||
|
|
@ -2623,6 +2632,7 @@ body.theme-dark {
|
|||
.manager-filter-field--compound {
|
||||
flex: 1 1 220px;
|
||||
max-width: none;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.manager-filter-field--search {
|
||||
|
|
@ -2692,6 +2702,11 @@ body.theme-dark {
|
|||
width: auto;
|
||||
}
|
||||
|
||||
.manager-filter-select-group .manager-multiselect-filter {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.manager-filter-select-group .manager-filter-operator {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
|
|
@ -2738,20 +2753,183 @@ body.theme-dark {
|
|||
transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
|
||||
}
|
||||
|
||||
.manager-container .manager-bar__search .dropdown select:focus,
|
||||
.manager-container .manager-bar__search .search-input-container input:focus,
|
||||
.manager-container .bpm-mobile-header__filters .dropdown select:focus,
|
||||
.manager-container .bpm-mobile-header__search .search-input-container input:focus {
|
||||
border-color: var(--interactive-accent);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .dropdown select {
|
||||
border: 1px solid var(--bpm-border);
|
||||
border-radius: var(--bpm-radius-sm);
|
||||
background: var(--bpm-surface);
|
||||
}
|
||||
|
||||
.manager-container .manager-bar__search .dropdown select:focus,
|
||||
.manager-container .manager-bar__search .search-input-container input:focus,
|
||||
.manager-container .bpm-mobile-header__filters .dropdown select:focus,
|
||||
.manager-container .bpm-mobile-header__search .search-input-container input:focus {
|
||||
border-color: var(--interactive-accent);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
min-height: 34px;
|
||||
height: 100%;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: var(--text-normal);
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__trigger:hover,
|
||||
.manager-multiselect-filter__trigger:focus-visible {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__summary {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
padding: 0 5px;
|
||||
border-radius: 9px;
|
||||
background: color-mix(in srgb, var(--interactive-accent) 16%, transparent);
|
||||
color: var(--text-accent);
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__count.is-empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__chevron {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--text-muted);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__chevron svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter.is-open .manager-multiselect-filter__chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__menu {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
top: calc(100% + 4px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
max-height: min(280px, 48vh);
|
||||
overflow-y: auto;
|
||||
padding: 4px;
|
||||
border: 1px solid var(--bpm-border);
|
||||
border-radius: var(--bpm-radius-sm);
|
||||
background: var(--background-primary);
|
||||
box-shadow: var(--shadow-s);
|
||||
}
|
||||
|
||||
.manager-multiselect-filter.is-open .manager-multiselect-filter__menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
min-height: 32px;
|
||||
padding: 6px 8px;
|
||||
border: 0;
|
||||
border-radius: var(--bpm-radius-xs);
|
||||
background: transparent;
|
||||
color: var(--text-normal);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__option:hover,
|
||||
.manager-multiselect-filter__option:focus-visible {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__option.is-selected {
|
||||
background: color-mix(in srgb, var(--interactive-accent) 12%, transparent);
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__check {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__check svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.manager-multiselect-filter__option-label {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .dropdown select {
|
||||
border: 1px solid var(--bpm-border);
|
||||
border-radius: var(--bpm-radius-sm);
|
||||
background: var(--bpm-surface);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .manager-multiselect-filter {
|
||||
flex: 1 1 auto;
|
||||
max-width: 220px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .manager-multiselect-filter__trigger {
|
||||
border: 1px solid var(--bpm-border);
|
||||
border-radius: var(--bpm-radius-sm);
|
||||
background: var(--bpm-surface);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .manager-multiselect-filter__menu {
|
||||
right: 0;
|
||||
left: auto;
|
||||
width: min(260px, 70vw);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .manager-filter-operator {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@
|
|||
"1.0.2": "1.5.8",
|
||||
"1.0.3": "1.5.8",
|
||||
"1.0.4": "1.5.8",
|
||||
"1.0.5": "1.5.8"
|
||||
"1.0.5": "1.5.8",
|
||||
"1.0.6": "1.5.8"
|
||||
}
|
||||
Loading…
Reference in a new issue