Skip to content

Rework: Dataset Settings #8732

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: functional_dataset_settings
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions frontend/javascripts/admin/account/account_auth_token_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button, Col, Row, Spin, Typography } from "antd";
import { useWkSelector } from "libs/react_hooks";
import Toast from "libs/toast";
import { useEffect, useState } from "react";
import { SettingsCard } from "./helpers/settings_card";
import { SettingsCard, type SettingsCardProps } from "./helpers/settings_card";
import { SettingsTitle } from "./helpers/settings_title";

const { Text } = Typography;
Expand Down Expand Up @@ -41,20 +41,20 @@ function AccountAuthTokenView() {
}
};

const APIitems = [
const APIitems: SettingsCardProps[] = [
{
title: "Auth Token",
value: (
content: (
<Text code copyable>
{currentToken}
</Text>
),
},
{
title: "Token Revocation",
explanation:
tooltip:
"Revoke your token if it has been compromised or if you suspect someone else has gained access to it. This will invalidate all active sessions.",
value: (
content: (
<Button icon={<SwapOutlined />} type="primary" ghost onClick={handleRevokeToken}>
Revoke and Generate New Token
</Button>
Expand All @@ -64,7 +64,7 @@ function AccountAuthTokenView() {
? [
{
title: "Organization ID",
value: (
content: (
<Text code copyable>
{activeUser.organization}
</Text>
Expand All @@ -74,7 +74,7 @@ function AccountAuthTokenView() {
: []),
{
title: "API Documentation",
value: (
content: (
<a href="https://docs.webknossos.org/webknossos-py/index.html">
Read the docs <ExportOutlined />
</a>
Expand All @@ -92,11 +92,7 @@ function AccountAuthTokenView() {
<Row gutter={[24, 24]} style={{ marginBottom: 24 }}>
{APIitems.map((item) => (
<Col span={12} key={item.title}>
<SettingsCard
title={item.title}
description={item.value}
explanation={item.explanation}
/>
<SettingsCard title={item.title} content={item.content} tooltip={item.tooltip} />
</Col>
))}
</Row>
Expand Down
10 changes: 5 additions & 5 deletions frontend/javascripts/admin/account/account_password_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useState } from "react";
import { useHistory } from "react-router-dom";
import { logoutUserAction } from "viewer/model/actions/user_actions";
import Store from "viewer/store";
import { SettingsCard } from "./helpers/settings_card";
import { SettingsCard, type SettingsCardProps } from "./helpers/settings_card";
import { SettingsTitle } from "./helpers/settings_title";
const FormItem = Form.Item;
const { Password } = Input;
Expand Down Expand Up @@ -155,10 +155,10 @@ function AccountPasswordView() {
setResetPasswordVisible(true);
}

const passKeyList = [
const passKeyList: SettingsCardProps[] = [
{
title: "Coming soon",
value: "Passwordless login with passkeys is coming soon",
content: "Passwordless login with passkeys is coming soon",
// action: <Button type="default" shape="circle" icon={<DeleteOutlined />} size="small" />,
action: undefined,
},
Expand All @@ -171,7 +171,7 @@ function AccountPasswordView() {
<Col span={12}>
<SettingsCard
title="Password"
description={getPasswordComponent()}
content={getPasswordComponent()}
action={
<Button
type="default"
Expand All @@ -189,7 +189,7 @@ function AccountPasswordView() {
<Row gutter={[24, 24]} style={{ marginBottom: 24 }}>
{passKeyList.map((item) => (
<Col span={12} key={item.title}>
<SettingsCard title={item.title} description={item.value} action={item.action} />
<SettingsCard title={item.title} content={item.content} action={item.action} />
</Col>
))}
</Row>
Expand Down
22 changes: 9 additions & 13 deletions frontend/javascripts/admin/account/account_profile_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { formatUserName } from "viewer/model/accessors/user_accessor";
import { setThemeAction } from "viewer/model/actions/ui_actions";
import { setActiveUserAction } from "viewer/model/actions/user_actions";
import Store from "viewer/store";
import { SettingsCard } from "./helpers/settings_card";
import { SettingsCard, type SettingsCardProps } from "./helpers/settings_card";
import { SettingsTitle } from "./helpers/settings_title";

function AccountProfileView() {
Expand Down Expand Up @@ -56,29 +56,29 @@ function AccountProfileView() {
},
];

const profileItems = [
const profileItems: SettingsCardProps[] = [
{
title: "Name",
value: formatUserName(activeUser, activeUser),
content: formatUserName(activeUser, activeUser),
},
{
title: "Email",
value: activeUser.email,
content: activeUser.email,
},
{
title: "Organization",
value: activeOrganization?.name || activeUser.organization,
content: activeOrganization?.name || activeUser.organization,
},
{
title: "Role",
value: role,
explanation: (
content: role,
tooltip: (
<a href="https://docs.webknossos.org/webknossos/users/access_rights.html">Learn More</a>
),
},
{
title: "Theme",
value: (
content: (
<Dropdown.Button menu={{ items: themeItems }} trigger={["click"]} icon={<DownOutlined />}>
{themeItems.find((item) => item.key === selectedTheme)?.label}
</Dropdown.Button>
Expand All @@ -95,11 +95,7 @@ function AccountProfileView() {
<Row gutter={[24, 24]} style={{ marginBottom: 24 }}>
{profileItems.map((item) => (
<Col span={12} key={item.title}>
<SettingsCard
title={item.title}
description={item.value}
explanation={item.explanation}
/>
<SettingsCard title={item.title} content={item.content} tooltip={item.tooltip} />
</Col>
))}
</Row>
Expand Down
25 changes: 13 additions & 12 deletions frontend/javascripts/admin/account/helpers/settings_card.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import { InfoCircleOutlined } from "@ant-design/icons";
import { Card, Flex, Popover, Typography } from "antd";
import { Card, Flex, Tooltip, Typography } from "antd";

interface SettingsCardProps {
export type SettingsCardProps = {
title: string;
description: React.ReactNode;
explanation?: React.ReactNode;
content: React.ReactNode;
tooltip?: React.ReactNode;
action?: React.ReactNode;
}
style?: React.CSSProperties;
};

export function SettingsCard({ title, description, explanation, action }: SettingsCardProps) {
export function SettingsCard({ title, content, tooltip, action, style }: SettingsCardProps) {
return (
<Card style={{ minHeight: 105 }}>
<Card style={{ minHeight: 105, ...style }}>
<Typography.Text type="secondary" style={{ fontSize: 14 }}>
<Flex justify="space-between">
<div>
{title}

{explanation != null ? (
<Popover content={explanation}>
<InfoCircleOutlined style={{ marginLeft: 4 }} />
</Popover>
{tooltip != null ? (
<Tooltip title={tooltip}>
<InfoCircleOutlined style={{ marginLeft: 8 }} />
</Tooltip>
) : null}
</div>
{action}
</Flex>
</Typography.Text>
<div style={{ fontSize: 16, marginTop: 4 }}>{description}</div>
<div style={{ fontSize: 16, marginTop: 4 }}>{content}</div>
</Card>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function OrganizationDangerZoneView({ organization }: { organization: API
/>
<SettingsCard
title="Danger Zone"
description={
content={
<Button
danger
loading={isDeleting}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,22 @@ export function OrganizationNotificationsView({ organization }: { organization:
<Col span={12}>
<SettingsCard
title="WEBKNOSSOS Plan & Subscription"
explanation="Get notified when your WK subscription is about to expire or reach user and storage limits."
description={ownerEmail}
tooltip="Get notified when your WK subscription is about to expire or reach user and storage limits."
content={ownerEmail}
/>
</Col>
<Col span={12}>
<SettingsCard
title="AI Job Completion"
explanation="Get notified when a background conversion or AI job is completed."
description="Users are notified individually."
tooltip="Get notified when a background conversion or AI job is completed."
content="Users are notified individually."
/>
</Col>
<Col span={12}>
<SettingsCard
title="New User Signup"
explanation="Get notified when a new user signs up to your organization."
description={getNewUserNotificationsSettings()}
tooltip="Get notified when a new user signs up to your organization."
content={getNewUserNotificationsSettings()}
/>
</Col>
</Row>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { getPricingPlanStatus, getUsers, updateOrganization } from "admin/rest_a
import { Button, Col, Row, Spin, Tooltip, Typography } from "antd";
import { formatCountToDataAmountUnit } from "libs/format_utils";
import Toast from "libs/toast";
import { useEffect, useState } from "react";
import { type Key, useEffect, useState } from "react";
import type { APIOrganization, APIPricingPlanStatus } from "types/api_types";
import { setActiveOrganizationAction } from "viewer/model/actions/organization_actions";
import { Store } from "viewer/singletons";
import { SettingsCard } from "../account/helpers/settings_card";
import { SettingsCard, type SettingsCardProps } from "../account/helpers/settings_card";
import {
PlanAboutToExceedAlert,
PlanExceededAlert,
Expand Down Expand Up @@ -114,11 +114,11 @@ export function OrganizationOverviewView({ organization }: { organization: APIOr
</Tooltip>
);

const orgaStats = [
const orgaStats: (SettingsCardProps & { key: Key })[] = [
{
key: "name",
title: "Name",
value: (
content: (
<Typography.Text
editable={{
onChange: setOrganizationName,
Expand All @@ -131,13 +131,13 @@ export function OrganizationOverviewView({ organization }: { organization: APIOr
{
key: "owner",
title: "Owner",
value: organization.ownerName,
content: organization.ownerName,
},
{
key: "plan",
title: "Current Plan",
value: organization.pricingPlan,
explanation: (
content: organization.pricingPlan,
tooltip: (
<a href="https://webknossos.org/pricing" target="_blank" rel="noopener noreferrer">
Compare all plans
</a>
Expand All @@ -146,20 +146,20 @@ export function OrganizationOverviewView({ organization }: { organization: APIOr
{
key: "users",
title: "Users",
value: `${activeUsersCount} / ${maxUsersCountLabel}`,
content: `${activeUsersCount} / ${maxUsersCountLabel}`,
action: upgradeUsersAction,
},
{
key: "storage",
title: "Storage",
value: `${usedStorageLabel} / ${includedStorageLabel}`,
content: `${usedStorageLabel} / ${includedStorageLabel}`,
action: upgradeStorageAction,
},

{
key: "credits",
title: "WEBKNOSSOS Credits",
value: organization.creditBalance || "N/A",
content: organization.creditBalance || "N/A",
action: buyMoreCreditsAction,
},
];
Expand All @@ -177,9 +177,9 @@ export function OrganizationOverviewView({ organization }: { organization: APIOr
<Col span={8} key={stat.key}>
<SettingsCard
title={stat.title}
description={stat.value}
content={stat.content}
action={stat.action}
explanation={stat.explanation}
tooltip={stat.tooltip}
/>
</Col>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,18 @@ export default function ColorLayerOrderingTable({

const isSettingEnabled = colorLayerNames && colorLayerNames.length > 1;
const sortingItems = isSettingEnabled ? colorLayerNames.map((name) => name) : [];
const collapsibleDisabledExplanation =
const settingsIsDisabledExplanation =
"The order of layers can only be configured when the dataset has multiple color layers.";

const panelTitle = (
<span style={{ width: "100%" }}>
{settings.colorLayerOrder}{" "}
<Tooltip
title={isSettingEnabled ? settingsTooltips.colorLayerOrder : collapsibleDisabledExplanation}
>
<InfoCircleOutlined style={{ color: "gray" }} />
</Tooltip>
</span>
);

const collapseItems: CollapseProps["items"] = [
{
label: panelTitle,
label: settingsTooltips.colorLayerOrder,
key: "1",
children: sortingItems.map((name) => <SortableListItem key={name} colorLayerName={name} />),
},
];

return (
return isSettingEnabled ? (
<DndContext
autoScroll={false}
onDragStart={() => {
Expand All @@ -89,8 +78,11 @@ export default function ColorLayerOrderingTable({
defaultActiveKey={[]}
collapsible={isSettingEnabled ? "header" : "disabled"}
items={collapseItems}
ghost
/>
</SortableContext>
</DndContext>
) : (
settingsIsDisabledExplanation
);
}
Loading
Loading