NotificationLayout.stories.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import type { Meta, StoryObj } from '@storybook/react-vite';
  2. import { InputNumber, Space } from 'antd';
  3. import {
  4. CloudServerOutlined,
  5. DashboardOutlined,
  6. DesktopOutlined,
  7. SafetyOutlined,
  8. ThunderboltOutlined,
  9. } from '@ant-design/icons';
  10. import { NotificationLayout } from './NotificationLayout';
  11. import { NotificationCard } from './NotificationCard';
  12. import { NotificationEvent } from './NotificationEvent';
  13. import { NotificationHeader } from './NotificationHeader';
  14. const noop = () => undefined;
  15. function OutboundGroup() {
  16. return (
  17. <NotificationCard
  18. icon={<CloudServerOutlined />}
  19. title="Outbound"
  20. extra={
  21. <NotificationHeader
  22. count={1}
  23. total={2}
  24. allSelected={false}
  25. indeterminate
  26. onToggleAll={noop}
  27. />
  28. }
  29. >
  30. <Space orientation="vertical" size={8} style={{ width: '100%' }}>
  31. <NotificationEvent label="Outbound went down" checked onToggle={noop} />
  32. <NotificationEvent label="Outbound recovered" checked={false} onToggle={noop} />
  33. </Space>
  34. </NotificationCard>
  35. );
  36. }
  37. function XrayGroup() {
  38. return (
  39. <NotificationCard
  40. icon={<ThunderboltOutlined />}
  41. title="Xray"
  42. extra={
  43. <NotificationHeader
  44. count={1}
  45. total={1}
  46. allSelected
  47. indeterminate={false}
  48. onToggleAll={noop}
  49. />
  50. }
  51. >
  52. <Space orientation="vertical" size={8} style={{ width: '100%' }}>
  53. <NotificationEvent label="Xray crashed" checked onToggle={noop} />
  54. </Space>
  55. </NotificationCard>
  56. );
  57. }
  58. function NodeGroup() {
  59. return (
  60. <NotificationCard
  61. icon={<DesktopOutlined />}
  62. title="Nodes"
  63. extra={
  64. <NotificationHeader
  65. count={0}
  66. total={2}
  67. allSelected={false}
  68. indeterminate={false}
  69. onToggleAll={noop}
  70. />
  71. }
  72. >
  73. <Space orientation="vertical" size={8} style={{ width: '100%' }}>
  74. <NotificationEvent label="Node went offline" checked={false} onToggle={noop} />
  75. <NotificationEvent label="Node back online" checked={false} onToggle={noop} />
  76. </Space>
  77. </NotificationCard>
  78. );
  79. }
  80. function SystemGroup() {
  81. return (
  82. <NotificationCard
  83. icon={<DashboardOutlined />}
  84. title="System"
  85. extra={
  86. <NotificationHeader
  87. count={2}
  88. total={2}
  89. allSelected
  90. indeterminate={false}
  91. onToggleAll={noop}
  92. />
  93. }
  94. >
  95. <Space orientation="vertical" size={8} style={{ width: '100%' }}>
  96. <NotificationEvent label="CPU usage above threshold (%)" checked onToggle={noop}>
  97. <InputNumber
  98. size="small"
  99. min={0}
  100. max={100}
  101. defaultValue={80}
  102. aria-label="CPU usage threshold percent"
  103. style={{ width: 80 }}
  104. />
  105. </NotificationEvent>
  106. <NotificationEvent label="Memory usage above threshold (%)" checked onToggle={noop}>
  107. <InputNumber
  108. size="small"
  109. min={0}
  110. max={100}
  111. defaultValue={90}
  112. aria-label="Memory usage threshold percent"
  113. style={{ width: 80 }}
  114. />
  115. </NotificationEvent>
  116. </Space>
  117. </NotificationCard>
  118. );
  119. }
  120. function SecurityGroup() {
  121. return (
  122. <NotificationCard
  123. icon={<SafetyOutlined />}
  124. title="Security"
  125. extra={
  126. <NotificationHeader
  127. count={1}
  128. total={1}
  129. allSelected
  130. indeterminate={false}
  131. onToggleAll={noop}
  132. />
  133. }
  134. >
  135. <Space orientation="vertical" size={8} style={{ width: '100%' }}>
  136. <NotificationEvent label="Panel login attempt" checked onToggle={noop} />
  137. </Space>
  138. </NotificationCard>
  139. );
  140. }
  141. const meta = {
  142. title: 'UI/Notifications/NotificationLayout',
  143. component: NotificationLayout,
  144. tags: ['autodocs'],
  145. parameters: {
  146. layout: 'padded',
  147. docs: {
  148. description: {
  149. component:
  150. 'Responsive auto-fit grid (min 260px columns) that arranges notification event-group cards; the Telegram and email notification tabs on the settings page render their groups inside it.',
  151. },
  152. },
  153. },
  154. argTypes: {
  155. children: { description: 'Grid items, typically one NotificationCard per event group.' },
  156. },
  157. } satisfies Meta<typeof NotificationLayout>;
  158. export default meta;
  159. type Story = StoryObj<typeof meta>;
  160. export const AllEventGroups: Story = {
  161. args: {
  162. children: (
  163. <>
  164. <OutboundGroup />
  165. <XrayGroup />
  166. <NodeGroup />
  167. <SystemGroup />
  168. <SecurityGroup />
  169. </>
  170. ),
  171. },
  172. };
  173. export const TwoGroups: Story = {
  174. args: {
  175. children: (
  176. <>
  177. <SystemGroup />
  178. <SecurityGroup />
  179. </>
  180. ),
  181. },
  182. };
  183. export const SingleGroup: Story = {
  184. args: {
  185. children: <OutboundGroup />,
  186. },
  187. };