mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-03 06:55:44 +00:00
Merge pull request #4 from Novaloop-AG/feature/user-directory-angular
Feature/user directory angular
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(ls:*)",
|
||||
"Bash(test:*)",
|
||||
"Bash(yarn test:*)",
|
||||
"Bash(npx tsc:*)",
|
||||
"Bash(yarn lint:types:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,7 @@ $event-highlight-bg-color: var(--timeline-highlights-color);
|
||||
|
||||
/* redirect some variables away from their hardcoded values in the light theme */
|
||||
$settings-grey-fg-color: $primary-content;
|
||||
$tab-label-active-fg-color: $primary-content;
|
||||
|
||||
/* --eventbubble colors */
|
||||
$eventbubble-self-bg: var(--eventbubble-self-bg, $eventbubble-self-bg);
|
||||
|
||||
@@ -23,8 +23,10 @@ import LockIcon from "@vector-im/compound-design-tokens/assets/web/icons/lock";
|
||||
import BlockIcon from "@vector-im/compound-design-tokens/assets/web/icons/block";
|
||||
|
||||
import TabbedView, { Tab, useActiveTabWithDefault } from "../../structures/TabbedView";
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import { _t, _td, type TranslationKey } from "../../../languageHandler";
|
||||
import AccountUserSettingsTab from "../settings/tabs/user/AccountUserSettingsTab";
|
||||
import { useModuleSettingsTabs } from "../../../modules/ExtrasApi";
|
||||
import { ModuleApi } from "../../../modules/Api";
|
||||
import AppearanceUserSettingsTab from "../settings/tabs/user/AppearanceUserSettingsTab";
|
||||
import SecurityUserSettingsTab from "../settings/tabs/user/SecurityUserSettingsTab";
|
||||
import NotificationUserSettingsTab from "../settings/tabs/user/NotificationUserSettingsTab";
|
||||
@@ -87,12 +89,19 @@ function titleForTabID(tabId: UserTab): React.ReactNode {
|
||||
return _t("settings|labs_mjolnir|dialog_title", undefined, subs);
|
||||
case UserTab.Help:
|
||||
return _t("setting|help_about|dialog_title", undefined, subs);
|
||||
default: {
|
||||
// Module-registered tab — look up the label from the extras API
|
||||
const moduleTab = ModuleApi.instance.extras.settingsTabs.get(tabId);
|
||||
if (moduleTab) return moduleTab.label;
|
||||
return tabId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default function UserSettingsDialog(props: IProps): JSX.Element {
|
||||
const voipEnabled = useSettingValue(UIFeature.Voip);
|
||||
const mjolnirEnabled = useSettingValue("feature_mjolnir");
|
||||
const moduleSettingsTabs = useModuleSettingsTabs(ModuleApi.instance.extras);
|
||||
// store these props in state as changing tabs back and forth should clear them
|
||||
const [showMsc4108QrCode, setShowMsc4108QrCode] = useState(props.showMsc4108QrCode);
|
||||
const [initialEncryptionState, setInitialEncryptionState] = useState(props.initialEncryptionState);
|
||||
@@ -120,7 +129,20 @@ export default function UserSettingsDialog(props: IProps): JSX.Element {
|
||||
const getTabs = (): NonEmptyArray<Tab<UserTab>> => {
|
||||
const tabs: Tab<UserTab>[] = [];
|
||||
|
||||
tabs.push(
|
||||
// Prepend module-registered settings tabs (e.g. HealthChat "Profil")
|
||||
for (const moduleTab of moduleSettingsTabs) {
|
||||
tabs.push(
|
||||
new Tab(
|
||||
moduleTab.key as UserTab,
|
||||
moduleTab.label as TranslationKey,
|
||||
moduleTab.icon,
|
||||
moduleTab.body(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// JP: Disabled Account tab for HealthChat (replaced by module "Profil" tab)
|
||||
/*tabs.push(
|
||||
new Tab(
|
||||
UserTab.Account,
|
||||
_td("settings|account|title"),
|
||||
@@ -128,7 +150,7 @@ export default function UserSettingsDialog(props: IProps): JSX.Element {
|
||||
<AccountUserSettingsTab closeSettingsFn={props.onFinished} />,
|
||||
"UserSettingsGeneral",
|
||||
),
|
||||
);
|
||||
);*/
|
||||
tabs.push(
|
||||
new Tab(
|
||||
UserTab.SessionManager,
|
||||
@@ -249,7 +271,8 @@ export default function UserSettingsDialog(props: IProps): JSX.Element {
|
||||
return tabs as NonEmptyArray<Tab<UserTab>>;
|
||||
};
|
||||
|
||||
const [activeTabId, _setActiveTabId] = useActiveTabWithDefault(getTabs(), UserTab.Account, props.initialTabId);
|
||||
const defaultTab = moduleSettingsTabs.length > 0 ? (moduleSettingsTabs[0].key as UserTab) : UserTab.Account;
|
||||
const [activeTabId, _setActiveTabId] = useActiveTabWithDefault(getTabs(), defaultTab, props.initialTabId);
|
||||
const setActiveTabId = (tabId: UserTab): void => {
|
||||
_setActiveTabId(tabId);
|
||||
// Clear these so switching away from the tab and back to it will not show the QR code again
|
||||
|
||||
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import { type JSX, useState } from "react";
|
||||
import { type SpacePanelItemProps, type ExtrasApi } from "@element-hq/element-web-module-api";
|
||||
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
@@ -15,17 +15,27 @@ export interface ModuleSpacePanelItem extends SpacePanelItemProps {
|
||||
spaceKey: string;
|
||||
}
|
||||
|
||||
/** Shape of a settings tab registered by a module plugin. */
|
||||
export interface ModuleSettingsTab {
|
||||
label: string;
|
||||
icon: JSX.Element | string | null;
|
||||
body: () => JSX.Element;
|
||||
}
|
||||
|
||||
enum ExtrasApiEvent {
|
||||
SpacePanelItemsChanged = "SpacePanelItemsChanged",
|
||||
SettingsTabsChanged = "SettingsTabsChanged",
|
||||
}
|
||||
|
||||
interface EmittedEvents {
|
||||
[ExtrasApiEvent.SpacePanelItemsChanged]: () => void;
|
||||
[ExtrasApiEvent.SettingsTabsChanged]: () => void;
|
||||
}
|
||||
|
||||
export class ElementWebExtrasApi extends TypedEventEmitter<keyof EmittedEvents, EmittedEvents> implements ExtrasApi {
|
||||
public spacePanelItems = new Map<string, SpacePanelItemProps>();
|
||||
public visibleRoomBySpaceKey = new Map<string, () => string[]>();
|
||||
public settingsTabs = new Map<string, ModuleSettingsTab>();
|
||||
|
||||
public setSpacePanelItem(spacekey: string, item: SpacePanelItemProps): void {
|
||||
this.spacePanelItems.set(spacekey, item);
|
||||
@@ -35,6 +45,11 @@ export class ElementWebExtrasApi extends TypedEventEmitter<keyof EmittedEvents,
|
||||
public getVisibleRoomBySpaceKey(spaceKey: string, cb: () => string[]): void {
|
||||
this.visibleRoomBySpaceKey.set(spaceKey, cb);
|
||||
}
|
||||
|
||||
public registerSettingsTab(key: string, tab: ModuleSettingsTab): void {
|
||||
this.settingsTabs.set(key, tab);
|
||||
this.emit(ExtrasApiEvent.SettingsTabsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
export function useModuleSpacePanelItems(api: ElementWebExtrasApi): ModuleSpacePanelItem[] {
|
||||
@@ -53,3 +68,24 @@ export function useModuleSpacePanelItems(api: ElementWebExtrasApi): ModuleSpaceP
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
export interface ModuleSettingsTabEntry extends ModuleSettingsTab {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export function useModuleSettingsTabs(api: ElementWebExtrasApi): ModuleSettingsTabEntry[] {
|
||||
const getTabs = (): ModuleSettingsTabEntry[] => {
|
||||
return Array.from(api.settingsTabs.entries()).map(([key, tab]) => ({
|
||||
key,
|
||||
...tab,
|
||||
}));
|
||||
};
|
||||
|
||||
const [tabs, setTabs] = useState<ModuleSettingsTabEntry[]>(getTabs);
|
||||
|
||||
useTypedEventEmitter(api, ExtrasApiEvent.SettingsTabsChanged, () => {
|
||||
setTabs(getTabs());
|
||||
});
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user