mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 05:41:09 +02:00
feat(shared): add helpHref/themesHref to PillNav, shared Mana & Privacy FAQs
- PillNavigation: add helpHref and themesHref props with help icon in account dropdown - PillDropdown: add help icon (question mark circle) to iconPaths - shared-help-types: add getManaFAQs/getManaFeature for shared Mana credit FAQs - shared-help-types: add getPrivacyFAQs for shared privacy/GDPR/tech independence FAQs - ManaScore: add Help-Seite and Feedback-Seite as UX criteria, shared-help-ui and shared-feedback-ui as Core cross-app packages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6efeadb39e
commit
13681df76c
6 changed files with 242 additions and 11 deletions
|
|
@ -145,17 +145,18 @@ Bewertet die Sicherheitsmaßnahmen.
|
|||
|
||||
Bewertet die User Experience und Accessibility.
|
||||
|
||||
| Kriterium | Punkte |
|
||||
| ---------------------------- | ------ |
|
||||
| i18n (mindestens 5 Sprachen) | 0-20 |
|
||||
| Responsive Design | 0-15 |
|
||||
| Keyboard Navigation | 0-10 |
|
||||
| Focus Trapping (Modals) | 0-10 |
|
||||
| ARIA Labels/Roles | 0-10 |
|
||||
| Toast/Feedback System | 0-10 |
|
||||
| Loading/Skeleton States | 0-10 |
|
||||
| Dark/Light Mode | 0-10 |
|
||||
| Immersive Mode | 0-5 |
|
||||
| Kriterium | Punkte |
|
||||
| -------------------------------- | ------ |
|
||||
| i18n (mindestens 5 Sprachen) | 0-15 |
|
||||
| Responsive Design | 0-15 |
|
||||
| Keyboard Navigation | 0-10 |
|
||||
| Focus Trapping (Modals) | 0-10 |
|
||||
| ARIA Labels/Roles | 0-10 |
|
||||
| Toast/Feedback System | 0-10 |
|
||||
| Loading/Skeleton States | 0-10 |
|
||||
| Dark/Light Mode | 0-10 |
|
||||
| Help-Seite (shared-help-ui) | 0-5 |
|
||||
| Feedback-Seite (shared-feedback) | 0-5 |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -229,6 +230,8 @@ Misst wie konsequent eine App die shared Packages des Monorepos nutzt:
|
|||
| `shared-branding` | Core | App-Icons, Farben, URLs |
|
||||
| `shared-i18n` | Core | Internationalisierung (Sprach-Utilities) |
|
||||
| `shared-error-tracking` | Core | GlitchTip Error Tracking |
|
||||
| `shared-help-ui` | Core | Hilfe-Seite mit FAQ, Features, Shortcuts |
|
||||
| `shared-feedback-ui` | Core | Feedback-Seite für Nutzer-Rückmeldungen |
|
||||
| `shared-storage` | Optional | S3/MinIO Datei-Upload (nur wenn relevant) |
|
||||
| `shared-llm` | Optional | LLM-Integration (nur wenn AI-Features) |
|
||||
|
||||
|
|
|
|||
|
|
@ -11,3 +11,9 @@ export * from './schemas.js';
|
|||
|
||||
// Search types
|
||||
export * from './search.js';
|
||||
|
||||
// Shared Mana FAQ content
|
||||
export { getManaFAQs, getManaFeature } from './mana-faq.js';
|
||||
|
||||
// Shared Privacy FAQ content
|
||||
export { getPrivacyFAQs, type PrivacyFAQOptions } from './privacy-faq.js';
|
||||
|
|
|
|||
95
packages/shared-help-types/src/mana-faq.ts
Normal file
95
packages/shared-help-types/src/mana-faq.ts
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* Shared Mana/Credits FAQ content
|
||||
* Reusable across all apps that have a /mana subscription page
|
||||
*/
|
||||
|
||||
import type { FAQItem, FeatureItem } from './content.js';
|
||||
|
||||
/**
|
||||
* Returns shared FAQ items explaining the Mana credit system.
|
||||
* Apps can spread these into their help content's faq array.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getManaFAQs } from '@manacore/shared-help-types';
|
||||
*
|
||||
* export function getMyAppHelpContent(locale: string): HelpContent {
|
||||
* return {
|
||||
* faq: [
|
||||
* ...appSpecificFaqs,
|
||||
* ...getManaFAQs(locale),
|
||||
* ],
|
||||
* ...
|
||||
* };
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function getManaFAQs(locale: string): FAQItem[] {
|
||||
const isDE = locale === 'de';
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'faq-mana-what',
|
||||
question: isDE ? 'Was ist Mana?' : 'What is Mana?',
|
||||
answer: isDE
|
||||
? '<p><strong>Mana</strong> ist die universelle Währung im ManaCore-Ökosystem. Mit Mana bezahlst du für Premium-Funktionen wie KI-Generierungen, Cloud-Modelle und erweiterte Features — app-übergreifend mit einem einzigen Guthaben.</p><ul><li>1 Mana ≈ 1 Cent (im Abo)</li><li>Dein Guthaben gilt in <strong>allen ManaCore-Apps</strong></li><li>Jede App zeigt deinen aktuellen Stand unter <strong>Mana</strong> im Account-Menü</li></ul>'
|
||||
: '<p><strong>Mana</strong> is the universal currency in the ManaCore ecosystem. With Mana you pay for premium features like AI generations, cloud models, and advanced features — across all apps with a single balance.</p><ul><li>1 Mana ≈ 1 cent (with subscription)</li><li>Your balance works across <strong>all ManaCore apps</strong></li><li>Each app shows your current balance under <strong>Mana</strong> in the account menu</li></ul>',
|
||||
category: 'billing',
|
||||
order: 90,
|
||||
language: isDE ? 'de' : 'en',
|
||||
featured: true,
|
||||
tags: isDE
|
||||
? ['mana', 'credits', 'guthaben', 'währung']
|
||||
: ['mana', 'credits', 'balance', 'currency'],
|
||||
},
|
||||
{
|
||||
id: 'faq-mana-get',
|
||||
question: isDE ? 'Wie bekomme ich Mana?' : 'How do I get Mana?',
|
||||
answer: isDE
|
||||
? '<p>Es gibt drei Wege, Mana zu erhalten:</p><ul><li><strong>Free-Tier</strong>: Jeder Nutzer erhält <strong>150 Mana/Monat</strong> kostenlos</li><li><strong>Mana Stream</strong> (Abo): Monatliche Mana-Pakete von 600 bis 5.000 Mana (ab 6€/Monat, 20% Jahresrabatt)</li><li><strong>Mana Trank</strong> (Einmalkauf): Sofort-Pakete von 350 bis 2.800 Mana (ab 4,90€)</li></ul><p>Abonnenten können außerdem Mana an andere Nutzer <strong>verschenken</strong>.</p>'
|
||||
: '<p>There are three ways to get Mana:</p><ul><li><strong>Free tier</strong>: Every user receives <strong>150 Mana/month</strong> for free</li><li><strong>Mana Stream</strong> (subscription): Monthly Mana packages from 600 to 5,000 Mana (from €6/month, 20% yearly discount)</li><li><strong>Mana Potion</strong> (one-time purchase): Instant packages from 350 to 2,800 Mana (from €4.90)</li></ul><p>Subscribers can also <strong>gift</strong> Mana to other users.</p>',
|
||||
category: 'billing',
|
||||
order: 91,
|
||||
language: isDE ? 'de' : 'en',
|
||||
tags: isDE
|
||||
? ['mana', 'kaufen', 'abo', 'kostenlos', 'stream', 'trank']
|
||||
: ['mana', 'buy', 'subscription', 'free', 'stream', 'potion'],
|
||||
},
|
||||
{
|
||||
id: 'faq-mana-use',
|
||||
question: isDE ? 'Wofür wird Mana verwendet?' : 'What is Mana used for?',
|
||||
answer: isDE
|
||||
? '<p>Mana wird für Premium-Funktionen innerhalb der ManaCore-Apps verwendet:</p><ul><li><strong>Chat</strong>: Cloud-KI-Modelle (Claude, GPT, DeepSeek) — lokale Modelle sind kostenlos</li><li><strong>Picture</strong>: KI-Bildgenerierungen (nach 3 kostenlosen Generierungen)</li><li><strong>Context</strong>: KI-Textgenerierung und -analyse</li><li><strong>Weitere Apps</strong>: KI-gestützte Features in Planta, Questions, etc.</li></ul><p>Basis-Funktionen wie Aufgaben, Kalender, Kontakte, Dateien und Chats mit lokalen Modellen sind <strong>immer kostenlos</strong>.</p>'
|
||||
: '<p>Mana is used for premium features within ManaCore apps:</p><ul><li><strong>Chat</strong>: Cloud AI models (Claude, GPT, DeepSeek) — local models are free</li><li><strong>Picture</strong>: AI image generations (after 3 free generations)</li><li><strong>Context</strong>: AI text generation and analysis</li><li><strong>More apps</strong>: AI-powered features in Planta, Questions, etc.</li></ul><p>Core features like tasks, calendar, contacts, files, and chats with local models are <strong>always free</strong>.</p>',
|
||||
category: 'billing',
|
||||
order: 92,
|
||||
language: isDE ? 'de' : 'en',
|
||||
tags: isDE
|
||||
? ['mana', 'verbrauch', 'kosten', 'kostenlos']
|
||||
: ['mana', 'usage', 'costs', 'free'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shared feature item for the Mana credit system.
|
||||
*/
|
||||
export function getManaFeature(locale: string): FeatureItem {
|
||||
const isDE = locale === 'de';
|
||||
|
||||
return {
|
||||
id: 'feature-mana',
|
||||
title: isDE ? 'Mana-Credits' : 'Mana Credits',
|
||||
description: isDE
|
||||
? 'Universelles Guthaben für Premium-Features in allen ManaCore-Apps — 150 Mana/Monat kostenlos.'
|
||||
: 'Universal balance for premium features across all ManaCore apps — 150 Mana/month for free.',
|
||||
icon: '✨',
|
||||
category: 'core',
|
||||
highlights: isDE
|
||||
? ['150 Mana/Monat kostenlos', 'App-übergreifend', 'Abos & Einmalkäufe', 'Mana verschenken']
|
||||
: ['150 Mana/month free', 'Cross-app', 'Subscriptions & one-time', 'Gift Mana'],
|
||||
content: '',
|
||||
order: 99,
|
||||
language: isDE ? 'de' : 'en',
|
||||
};
|
||||
}
|
||||
109
packages/shared-help-types/src/privacy-faq.ts
Normal file
109
packages/shared-help-types/src/privacy-faq.ts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Shared Privacy, Data Protection & Tech Independence FAQ content
|
||||
* Reusable across all apps — covers GDPR, encryption, self-hosting,
|
||||
* tech stack independence, data export, account deletion
|
||||
*/
|
||||
|
||||
import type { FAQItem } from './content.js';
|
||||
|
||||
export interface PrivacyFAQOptions {
|
||||
/**
|
||||
* What kind of data does the app handle?
|
||||
* Used in the main privacy FAQ to make it specific.
|
||||
* @example 'Aufgaben' / 'tasks', 'Dateien' / 'files', 'Chats' / 'chats'
|
||||
*/
|
||||
dataTypeDE: string;
|
||||
dataTypeEN: string;
|
||||
|
||||
/**
|
||||
* Optional extra bullet points for the main privacy FAQ (app-specific).
|
||||
* Each entry is a single `<li>` string (without the `<li>` tags).
|
||||
* @example ['<strong>Lokale Modelle</strong>: Deine Daten verlassen nie unseren Server']
|
||||
*/
|
||||
extraBulletsDE?: string[];
|
||||
extraBulletsEN?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns shared FAQ items covering privacy, data protection, and tech independence.
|
||||
* The main privacy FAQ can be customized per app via options.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getPrivacyFAQs } from '@manacore/shared-help-types';
|
||||
*
|
||||
* const privacyFAQs = getPrivacyFAQs(locale, {
|
||||
* dataTypeDE: 'Aufgaben',
|
||||
* dataTypeEN: 'tasks',
|
||||
* extraBulletsDE: ['<strong>Offline</strong>: Funktioniert auch ohne Internet'],
|
||||
* extraBulletsEN: ['<strong>Offline</strong>: Works without internet'],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export function getPrivacyFAQs(locale: string, options: PrivacyFAQOptions): FAQItem[] {
|
||||
const isDE = locale === 'de';
|
||||
|
||||
const extraDE = (options.extraBulletsDE || []).map((b) => `<li>${b}</li>`).join('');
|
||||
const extraEN = (options.extraBulletsEN || []).map((b) => `<li>${b}</li>`).join('');
|
||||
|
||||
return [
|
||||
{
|
||||
id: 'faq-privacy',
|
||||
question: isDE
|
||||
? `Wie werden meine ${options.dataTypeDE} geschützt?`
|
||||
: `How are my ${options.dataTypeEN} protected?`,
|
||||
answer: isDE
|
||||
? `<p>Deine Daten sind sicher bei ManaCore:</p><ul><li><strong>Verschlüsselung</strong>: Alle Daten werden bei der Übertragung (TLS) verschlüsselt</li><li><strong>DSGVO-konform</strong>: Wir halten uns an die EU-Datenschutzverordnung</li><li><strong>Kein Datenverkauf</strong>: Deine ${options.dataTypeDE} werden nie an Dritte verkauft oder für Werbung genutzt</li><li><strong>Self-Hosted</strong>: ManaCore läuft auf eigenen Servern — keine Abhängigkeit von Cloud-Anbietern wie AWS oder Google</li><li><strong>Open Source</strong>: Der Quellcode ist einsehbar — Transparenz statt Vertrauen</li>${extraDE}</ul>`
|
||||
: `<p>Your data is secure with ManaCore:</p><ul><li><strong>Encryption</strong>: All data is encrypted in transit (TLS)</li><li><strong>GDPR compliant</strong>: We follow EU data protection regulations</li><li><strong>No data selling</strong>: Your ${options.dataTypeEN} are never sold to third parties or used for advertising</li><li><strong>Self-hosted</strong>: ManaCore runs on its own servers — no dependency on cloud providers like AWS or Google</li><li><strong>Open source</strong>: The source code is viewable — transparency over trust</li>${extraEN}</ul>`,
|
||||
category: 'privacy',
|
||||
order: 95,
|
||||
language: isDE ? 'de' : 'en',
|
||||
featured: true,
|
||||
tags: isDE
|
||||
? ['datenschutz', 'dsgvo', 'sicherheit', 'verschlüsselung']
|
||||
: ['privacy', 'gdpr', 'security', 'encryption'],
|
||||
},
|
||||
{
|
||||
id: 'faq-tech-independence',
|
||||
question: isDE
|
||||
? 'Wie unabhängig ist ManaCore von großen Tech-Konzernen?'
|
||||
: 'How independent is ManaCore from big tech companies?',
|
||||
answer: isDE
|
||||
? '<p>ManaCore ist bewusst <strong>technologisch unabhängig</strong> aufgebaut:</p><ul><li><strong>Eigene Server</strong>: Alle Dienste laufen auf einem eigenen Mac Mini Server — kein AWS, kein Google Cloud, kein Azure</li><li><strong>Eigene KI</strong>: Lokale KI-Modelle (Gemma, Qwen, LLaVA) laufen auf unserem eigenen GPU-Server mit NVIDIA RTX 3090 — deine Daten verlassen nie unsere Infrastruktur</li><li><strong>Keine Google/Apple-Anmeldung</strong>: Eigenes Auth-System (Mana Core Auth) — kein OAuth über Drittanbieter, keine Tracking-Cookies von Google oder Facebook</li><li><strong>Eigene Suche</strong>: SearXNG Meta-Suchmaschine statt Google Search API</li><li><strong>Eigener Speicher</strong>: MinIO (S3-kompatibel) statt AWS S3 oder Google Cloud Storage</li><li><strong>Eigene Datenbank</strong>: PostgreSQL auf eigenem Server statt Cloud-Datenbanken</li><li><strong>Keine Tracking-SDKs</strong>: Kein Google Analytics, kein Facebook Pixel, kein Amplitude — eigene Analytics mit Umami</li></ul><p>Das Ziel: Ein digitales Zuhause, das dir gehört — nicht Big Tech.</p>'
|
||||
: '<p>ManaCore is deliberately built to be <strong>technologically independent</strong>:</p><ul><li><strong>Own servers</strong>: All services run on a dedicated Mac Mini server — no AWS, no Google Cloud, no Azure</li><li><strong>Own AI</strong>: Local AI models (Gemma, Qwen, LLaVA) run on our own GPU server with NVIDIA RTX 3090 — your data never leaves our infrastructure</li><li><strong>No Google/Apple login</strong>: Own auth system (Mana Core Auth) — no OAuth via third parties, no tracking cookies from Google or Facebook</li><li><strong>Own search</strong>: SearXNG meta-search engine instead of Google Search API</li><li><strong>Own storage</strong>: MinIO (S3-compatible) instead of AWS S3 or Google Cloud Storage</li><li><strong>Own database</strong>: PostgreSQL on own server instead of cloud databases</li><li><strong>No tracking SDKs</strong>: No Google Analytics, no Facebook Pixel, no Amplitude — own analytics with Umami</li></ul><p>The goal: A digital home that belongs to you — not big tech.</p>',
|
||||
category: 'privacy',
|
||||
order: 96,
|
||||
language: isDE ? 'de' : 'en',
|
||||
featured: true,
|
||||
tags: isDE
|
||||
? ['unabhängig', 'self-hosted', 'eigene-server', 'kein-google', 'kein-aws']
|
||||
: ['independent', 'self-hosted', 'own-servers', 'no-google', 'no-aws'],
|
||||
},
|
||||
{
|
||||
id: 'faq-data-export',
|
||||
question: isDE ? 'Kann ich meine Daten exportieren?' : 'Can I export my data?',
|
||||
answer: isDE
|
||||
? '<p>Ja! Du hast jederzeit volle Kontrolle über deine Daten:</p><ul><li><strong>Datenexport</strong>: Exportiere alle deine Daten in gängigen, offenen Formaten (JSON, CSV, vCard, iCal — je nach App)</li><li><strong>Datenportabilität</strong>: Gemäß DSGVO Art. 20 hast du das Recht auf Datenübertragbarkeit</li><li><strong>Keine Vendor-Lock-in</strong>: Deine Daten gehören dir — nicht uns. Wir nutzen offene Standards, damit du jederzeit zu einem anderen Dienst wechseln kannst</li><li><strong>Standard-Formate</strong>: Keine proprietären Formate — alles ist mit gängigen Tools les- und importierbar</li></ul>'
|
||||
: '<p>Yes! You have full control over your data at all times:</p><ul><li><strong>Data export</strong>: Export all your data in common, open formats (JSON, CSV, vCard, iCal — depending on the app)</li><li><strong>Data portability</strong>: Under GDPR Art. 20 you have the right to data portability</li><li><strong>No vendor lock-in</strong>: Your data belongs to you — not us. We use open standards so you can switch to another service at any time</li><li><strong>Standard formats</strong>: No proprietary formats — everything is readable and importable with common tools</li></ul>',
|
||||
category: 'privacy',
|
||||
order: 97,
|
||||
language: isDE ? 'de' : 'en',
|
||||
tags: isDE
|
||||
? ['export', 'daten', 'portabilität', 'dsgvo', 'offene-formate']
|
||||
: ['export', 'data', 'portability', 'gdpr', 'open-formats'],
|
||||
},
|
||||
{
|
||||
id: 'faq-account-deletion',
|
||||
question: isDE ? 'Kann ich mein Konto löschen?' : 'Can I delete my account?',
|
||||
answer: isDE
|
||||
? '<p>Ja, jederzeit:</p><ul><li>Gehe zu <strong>Profil > Konto löschen</strong></li><li>Alle deine Daten werden <strong>dauerhaft und unwiderruflich</strong> gelöscht</li><li>Dies umfasst alle Inhalte, Einstellungen und persönlichen Daten</li><li>Geteilte Inhalte (z.B. Share-Links) werden ebenfalls deaktiviert</li></ul><p>Wir empfehlen, vorher einen Datenexport durchzuführen.</p>'
|
||||
: '<p>Yes, at any time:</p><ul><li>Go to <strong>Profile > Delete Account</strong></li><li>All your data will be <strong>permanently and irreversibly</strong> deleted</li><li>This includes all content, settings, and personal data</li><li>Shared content (e.g., share links) will also be deactivated</li></ul><p>We recommend performing a data export beforehand.</p>',
|
||||
category: 'privacy',
|
||||
order: 98,
|
||||
language: isDE ? 'de' : 'en',
|
||||
tags: isDE
|
||||
? ['konto', 'löschen', 'daten', 'entfernen']
|
||||
: ['account', 'delete', 'data', 'remove'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -123,6 +123,8 @@
|
|||
'M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1',
|
||||
// App icons
|
||||
grid: 'M4 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM14 5a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1V5zM4 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1H5a1 1 0 01-1-1v-4zM14 15a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z',
|
||||
// Help icon (question mark circle)
|
||||
help: 'M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm2-1.645A3.502 3.502 0 0012 6.5 3.501 3.501 0 008.645 9h2.012A1.5 1.5 0 0112 8.5c.828 0 1.5.672 1.5 1.5 0 .828-.672 1.5-1.5 1.5a1 1 0 00-1 1V14h2v-.645z',
|
||||
// Mana icon (water drop)
|
||||
mana: 'M12.3 1c.03.05 7.3 9.67 7.3 13.7 0 4.03-3.27 7.3-7.3 7.3S5 18.73 5 14.7C5 10.66 12.3 1 12.3 1zm0 6.4c-.02.03-3.65 4.83-3.65 6.84 0 2.02 1.64 3.65 3.65 3.65s3.65-1.64 3.65-3.65c0-2.01-3.62-6.81-3.65-6.84z',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -282,6 +282,8 @@
|
|||
themesHref?: string;
|
||||
/** Spiral page href (shown in user dropdown). Set to empty string to hide. */
|
||||
spiralHref?: string;
|
||||
/** Help page href (shown in user dropdown). Set to empty string to hide. */
|
||||
helpHref?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -327,6 +329,7 @@
|
|||
feedbackHref = '/feedback',
|
||||
themesHref,
|
||||
spiralHref,
|
||||
helpHref,
|
||||
}: Props = $props();
|
||||
|
||||
// Type guards for elements
|
||||
|
|
@ -873,6 +876,19 @@
|
|||
},
|
||||
]
|
||||
: []),
|
||||
...(helpHref
|
||||
? [
|
||||
{
|
||||
id: 'help',
|
||||
label: 'Hilfe',
|
||||
icon: 'help',
|
||||
onClick: () => {
|
||||
window.location.href = helpHref;
|
||||
},
|
||||
active: currentPath === helpHref,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(showLanguageSwitcher && languageItems.length > 0
|
||||
? [
|
||||
{ id: 'language-divider', label: '', divider: true },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue