Files
3x-ui-agent/frontend/src/components/form/DateTimePicker.stories.tsx
T
Muse 1bd63e6625 settings trim: remove dead settings, upstream remnants, JSON/Clash subscriptions
Per SETTINGS-AUDIT (all three tiers approved 2026-10-23):

Dead settings:
- panelOutbound, ipLimitAllowlist (+ orphan parser job), outboundDownThreshold
- tg fake events outbound.down/outbound.up/xray.crash (no publisher in lite)
- phantom routing sub-tabs (Happ/Clash/Incy) and subJsonRules direct-rules tab
  (no backend keys); subHideSettings moved to the subscription info tab first

Upstream remnants:
- ldap* / smtp* model+schema keys, EmailNotifications orphan component
- twoFactorEnable/twoFactorToken + login-page probe (no backend handler)
- externalTrafficInform*

Newly approved removals:
- JSON subscription family (producer, routes, UA auto-detect, mux/finalmask/
  observatory) and Clash subscription family (producer, routes, UA detect)
- SubBalancer (table, service, controller, settings tab)
- subThemeDir (subscription page falls back to the built-in template)
- datepicker jalalian option (gregorian only; Persian picker removed)

JSON/Clash endpoints now 404; link-format output pinned by regression tests.
Guarded keys untouched: webListen/webPort/webBasePath/certs, tg* chain,
expireDiff/trafficDiff/tgBotProxy, subHideSettings, pageSize/tgLang.
2026-10-22 19:21:07 +00:00

84 lines
2.3 KiB
TypeScript

import { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react-vite';
import { Typography } from 'antd';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
import { setDatepicker } from '@/hooks/useDatepicker';
import { ThemeProvider } from '@/hooks/useTheme';
import DateTimePicker from './DateTimePicker';
setDatepicker('gregorian');
function ClientExpiryDemo() {
const [value, setValue] = useState<Dayjs | null>(dayjs('2026-12-31 23:59:59'));
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
<DateTimePicker value={value} onChange={setValue} placeholder="Expiry date" />
<Typography.Text type="secondary">
{value
? `user1@node-de expiryTime: ${value.valueOf()}`
: 'user1@node-de expiryTime: 0 (never expires)'}
</Typography.Text>
</div>
);
}
const meta = {
title: 'Form/DateTimePicker',
component: DateTimePicker,
tags: ['autodocs'],
parameters: {
layout: 'padded',
docs: {
description: {
component:
'Date/time picker used for client and inbound expiry dates, rendered with the AntD DatePicker.',
},
},
},
decorators: [
(Story) => (
<ThemeProvider>
<Story />
</ThemeProvider>
),
],
argTypes: {
value: { description: 'Selected moment as a Dayjs instance, or null when unset.' },
onChange: { description: 'Called with the picked Dayjs value, or null when cleared.' },
showTime: { description: 'Include an hour/minute/second selector alongside the date.' },
format: { description: 'Display format for the Gregorian picker input.' },
placeholder: { description: 'Input placeholder shown while no value is set.' },
disabled: { description: 'Disables the input and hides the clear button.' },
},
} satisfies Meta<typeof DateTimePicker>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Empty: Story = {
args: {
value: null,
onChange: () => undefined,
placeholder: 'Leave blank to never expire',
},
};
export const ClientExpiry: Story = {
args: { value: null, onChange: () => undefined },
render: () => <ClientExpiryDemo />,
};
export const DateOnly: Story = {
args: {
value: dayjs('2026-08-01'),
onChange: () => undefined,
showTime: false,
format: 'YYYY-MM-DD',
placeholder: 'Start date',
},
};