mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: Move plugin settings under separate section in config menu
This commit is contained in:
parent
fa9f5fd458
commit
63493214a0
@ -1,4 +1,4 @@
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import Setting, { SettingSectionSource } from '@joplin/lib/models/Setting';
|
||||
|
||||
const { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow } = require('./test-utils.js');
|
||||
|
||||
@ -121,7 +121,7 @@ describe('models_Setting', function() {
|
||||
}));
|
||||
|
||||
it('should register new sections', (async () => {
|
||||
await Setting.registerSection('mySection', {
|
||||
await Setting.registerSection('mySection', SettingSectionSource.Default, {
|
||||
label: 'My section',
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
import { SettingSectionSource } from '@joplin/lib/models/Setting';
|
||||
import * as React from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import Setting from '@joplin/lib/models/Setting';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
const styled = require('styled-components').default;
|
||||
const Setting = require('@joplin/lib/models/Setting').default;
|
||||
|
||||
interface Props {
|
||||
selection: string;
|
||||
@ -30,6 +33,21 @@ export const StyledListItem = styled.a`
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledDivider = styled.div`
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: ${(props: any) => props.theme.color2};
|
||||
padding: ${(props: any) => props.theme.mainPadding}px;
|
||||
padding-top: ${(props: any) => props.theme.mainPadding * .8}px;
|
||||
padding-bottom: ${(props: any) => props.theme.mainPadding * .8}px;
|
||||
border-top: 1px solid ${(props: any) => props.theme.dividerColor};
|
||||
border-bottom: 1px solid ${(props: any) => props.theme.dividerColor};
|
||||
background-color: ${(props: any) => props.theme.selectedColor2};
|
||||
font-size: ${(props: any) => Math.round(props.theme.fontSize)}px;
|
||||
opacity: 0.5;
|
||||
`;
|
||||
|
||||
export const StyledListItemLabel = styled.span`
|
||||
font-size: ${(props: any) => Math.round(props.theme.fontSize * 1.2)}px;
|
||||
font-weight: 500;
|
||||
@ -50,6 +68,20 @@ export const StyledListItemIcon = styled.i`
|
||||
export default function Sidebar(props: Props) {
|
||||
const buttons: any[] = [];
|
||||
|
||||
const sortedSections = useMemo(() => {
|
||||
const output = props.sections.slice();
|
||||
output.sort((a: any, b: any) => {
|
||||
const s1 = a.source || SettingSectionSource.Default;
|
||||
const s2 = b.source || SettingSectionSource.Default;
|
||||
if (s1 === SettingSectionSource.Default && s2 === SettingSectionSource.Default) return props.sections.indexOf(s1) - props.sections.indexOf(s2);
|
||||
if (s1 === SettingSectionSource.Default && s2 === SettingSectionSource.Plugin) return -1;
|
||||
if (s1 === SettingSectionSource.Plugin && s2 === SettingSectionSource.Default) return +1;
|
||||
return 0;
|
||||
});
|
||||
console.info('SORTED', output);
|
||||
return output;
|
||||
}, [props.sections]);
|
||||
|
||||
function renderButton(section: any) {
|
||||
const selected = props.selection === section.name;
|
||||
return (
|
||||
@ -62,7 +94,22 @@ export default function Sidebar(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
for (const section of props.sections) {
|
||||
function renderDivider(key: string) {
|
||||
return (
|
||||
<StyledDivider key={key}>
|
||||
{_('Plugins')}
|
||||
</StyledDivider>
|
||||
);
|
||||
}
|
||||
|
||||
let pluginDividerAdded = false;
|
||||
|
||||
for (const section of sortedSections) {
|
||||
if (section.source === SettingSectionSource.Plugin && !pluginDividerAdded) {
|
||||
buttons.push(renderDivider('divider-plugins'));
|
||||
pluginDividerAdded = true;
|
||||
}
|
||||
|
||||
buttons.push(renderButton(section));
|
||||
}
|
||||
|
||||
|
@ -62,11 +62,17 @@ interface CacheItem {
|
||||
value: any;
|
||||
}
|
||||
|
||||
export enum SettingSectionSource {
|
||||
Default = 1,
|
||||
Plugin = 2,
|
||||
}
|
||||
|
||||
export interface SettingSection {
|
||||
label: string;
|
||||
iconName?: string;
|
||||
description?: string;
|
||||
name?: string;
|
||||
source?: SettingSectionSource;
|
||||
}
|
||||
|
||||
interface SettingSections {
|
||||
@ -1009,8 +1015,8 @@ class Setting extends BaseModel {
|
||||
});
|
||||
}
|
||||
|
||||
static async registerSection(name: string, section: SettingSection) {
|
||||
this.customSections_[name] = { ...section, name: name };
|
||||
static async registerSection(name: string, source: SettingSectionSource, section: SettingSection) {
|
||||
this.customSections_[name] = { ...section, name: name, source: source };
|
||||
}
|
||||
|
||||
static settingMetadata(key: string): SettingItem {
|
||||
@ -1512,6 +1518,11 @@ class Setting extends BaseModel {
|
||||
throw new Error(`Invalid type ID: ${typeId}`);
|
||||
}
|
||||
|
||||
private static sectionSource(sectionName: string): SettingSectionSource {
|
||||
if (this.customSections_[sectionName]) return this.customSections_[sectionName].source || SettingSectionSource.Default;
|
||||
return SettingSectionSource.Default;
|
||||
}
|
||||
|
||||
static groupMetadatasBySections(metadatas: SettingItem[]) {
|
||||
const sections = [];
|
||||
const generalSection: any = { name: 'general', metadatas: [] };
|
||||
@ -1524,19 +1535,24 @@ class Setting extends BaseModel {
|
||||
generalSection.metadatas.push(md);
|
||||
} else {
|
||||
if (!nameToSections[md.section]) {
|
||||
nameToSections[md.section] = { name: md.section, metadatas: [] };
|
||||
nameToSections[md.section] = {
|
||||
name: md.section,
|
||||
metadatas: [],
|
||||
source: this.sectionSource(md.section),
|
||||
};
|
||||
sections.push(nameToSections[md.section]);
|
||||
}
|
||||
nameToSections[md.section].metadatas.push(md);
|
||||
}
|
||||
}
|
||||
|
||||
for (const name in this.customSections_) {
|
||||
nameToSections[name] = {
|
||||
name: name,
|
||||
metadatas: [],
|
||||
};
|
||||
}
|
||||
// for (const name in this.customSections_) {
|
||||
// nameToSections[name] = {
|
||||
// name: name,
|
||||
// source: this.customSections_[name].source,
|
||||
// metadatas: [],
|
||||
// };
|
||||
// }
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import eventManager from '../../../eventManager';
|
||||
import Setting, { SettingItem as InternalSettingItem } from '../../../models/Setting';
|
||||
import Setting, { SettingItem as InternalSettingItem, SettingSectionSource } from '../../../models/Setting';
|
||||
import Plugin from '../Plugin';
|
||||
import { SettingItem, SettingSection } from './types';
|
||||
|
||||
@ -71,7 +71,7 @@ export default class JoplinSettings {
|
||||
* Registers a new setting section. Like for registerSetting, it is dynamic and needs to be done every time the plugin starts.
|
||||
*/
|
||||
public async registerSection(name: string, section: SettingSection) {
|
||||
return Setting.registerSection(this.namespacedKey(name), section);
|
||||
return Setting.registerSection(this.namespacedKey(name), SettingSectionSource.Plugin, section);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user