Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Meta, StoryFn } from '@storybook/react/types-6-0';
import React from 'react';
import { TestContext } from '@kinvolk/headlamp-plugin/lib/testLib';
import AIAssistantHeader from './AIAssistantHeader';

export default {
title: 'components/assistant/AIAssistantHeader',
component: AIAssistantHeader,
decorators: [
(Story) => (
<TestContext>
<Story />
</TestContext>
),
],
} as Meta;

const Template: StoryFn<typeof AIAssistantHeader> = (args) => <AIAssistantHeader {...args} />;

export const Default = Template.bind({});
Default.args = {
isTestMode: false,
disableSettingsButton: false,
onClose: () => console.log('Close clicked'),
};

export const TestMode = Template.bind({});
TestMode.args = {
isTestMode: true,
disableSettingsButton: false,
onClose: () => console.log('Close clicked'),
};

export const DisabledSettings = Template.bind({});
DisabledSettings.args = {
isTestMode: false,
disableSettingsButton: true,
onClose: () => console.log('Close clicked'),
};
85 changes: 85 additions & 0 deletions ai-assistant/src/components/assistant/AIChatContent.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Meta, StoryFn } from '@storybook/react/types-6-0';
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import uses '@storybook/react/types-6-0' which is a Storybook v6-specific type path. While this exists in the codebase (app-catalog uses it), newer files in the repository use '@storybook/react' directly (see prometheus/src/components/Chart/Chart/chart.stories.tsx, app-catalog/src/components/charts/SettingsLink.stories.tsx). Consider using the modern import pattern for consistency with newer code, unless there's a specific reason to use the v6 type path.

Suggested change
import { Meta, StoryFn } from '@storybook/react/types-6-0';
import { Meta, StoryFn } from '@storybook/react';

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Apache 2.0 license header. All source files in this repository should include the Apache 2.0 license header with 2025 copyright year, as established in other source files throughout the codebase.

Copilot uses AI. Check for mistakes.
import React from 'react';
import { TestContext } from '@kinvolk/headlamp-plugin/lib/testLib';
import AIChatContent from './AIChatContent';

export default {
title: 'components/assistant/AIChatContent',
component: AIChatContent,
decorators: [
(Story) => (
<TestContext>
<Story />
</TestContext>
),
],
} as Meta;

const mockPromptHistory = [
{
role: 'user',
content: 'What is the status of my pods?',
},
{
role: 'assistant',
content: 'Based on the current cluster status, all pods are running normally. No issues detected.',
},
{
role: 'user',
content: 'Show me the deployment YAML',
},
{
role: 'assistant',
content: `apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 3
selector:
matchLabels:
app: example`,
},
];

const Template: StoryFn<typeof AIChatContent> = (args) => <AIChatContent {...args} />;

export const Default = Template.bind({});
Default.args = {
history: mockPromptHistory,
isLoading: false,
apiError: null,
onOperationSuccess: (response) => console.log('Operation success:', response),
onOperationFailure: (error, type, info) => console.log('Operation failed:', error, type, info),
onYamlAction: (yaml, title, type, isDelete) => console.log('YAML Action:', { yaml, title, type, isDelete }),
};

export const Empty = Template.bind({});
Empty.args = {
history: [],
isLoading: false,
apiError: null,
onOperationSuccess: (response) => console.log('Operation success:', response),
onOperationFailure: (error, type, info) => console.log('Operation failed:', error, type, info),
onYamlAction: (yaml, title, type, isDelete) => console.log('YAML Action:', { yaml, title, type, isDelete }),
};

export const WithError = Template.bind({});
WithError.args = {
history: [],
isLoading: false,
apiError: 'Failed to connect to AI service. Please check your API credentials in Settings.',
onOperationSuccess: (response) => console.log('Operation success:', response),
onOperationFailure: (error, type, info) => console.log('Operation failed:', error, type, info),
onYamlAction: (yaml, title, type, isDelete) => console.log('YAML Action:', { yaml, title, type, isDelete }),
};

export const Loading = Template.bind({});
Loading.args = {
history: mockPromptHistory,
isLoading: true,
apiError: null,
onOperationSuccess: (response) => console.log('Operation success:', response),
onOperationFailure: (error, type, info) => console.log('Operation failed:', error, type, info),
onYamlAction: (yaml, title, type, isDelete) => console.log('YAML Action:', { yaml, title, type, isDelete }),
};
124 changes: 124 additions & 0 deletions ai-assistant/src/components/common/ApiConfirmationDialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { Meta, StoryFn } from '@storybook/react/types-6-0';
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import uses '@storybook/react/types-6-0' which is a Storybook v6-specific type path. While this exists in the codebase (app-catalog uses it), newer files in the repository use '@storybook/react' directly (see prometheus/src/components/Chart/Chart/chart.stories.tsx, app-catalog/src/components/charts/SettingsLink.stories.tsx). Consider using the modern import pattern for consistency with newer code, unless there's a specific reason to use the v6 type path.

Suggested change
import { Meta, StoryFn } from '@storybook/react/types-6-0';
import { Meta, StoryFn } from '@storybook/react';

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Apache 2.0 license header. All source files in this repository should include the Apache 2.0 license header with 2025 copyright year, as established in other source files throughout the codebase.

Copilot uses AI. Check for mistakes.
import React from 'react';
import { TestContext } from '@kinvolk/headlamp-plugin/lib/testLib';
import ApiConfirmationDialog from './ApiConfirmationDialog';

export default {
title: 'components/common/ApiConfirmationDialog',
component: ApiConfirmationDialog,
decorators: [
(Story) => (
<TestContext>
<Story />
</TestContext>
),
],
} as Meta;

const mockYamlBody = `apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
config.yaml: |
app:
name: MyApp
version: 1.0.0
debug: true`;

const mockJsonBody = JSON.stringify(
{
apiVersion: 'v1',
kind: 'Pod',
metadata: {
name: 'example-pod',
namespace: 'default',
},
spec: {
containers: [
{
name: 'app',
image: 'myapp:latest',
ports: [{ containerPort: 8080 }],
},
],
},
},
null,
2
);

const Template: StoryFn<typeof ApiConfirmationDialog> = (args) => (
<div style={{ width: '100%', height: '100vh' }}>
<ApiConfirmationDialog {...args} />
</div>
);

export const Default = Template.bind({});
Default.args = {
open: true,
method: 'POST',
url: '/api/v1/namespaces/default/configmaps',
body: mockYamlBody,
onClose: () => console.log('Dialog closed'),
onConfirm: (editedBody, resourceInfo) =>
console.log('Confirmed', { editedBody, resourceInfo }),
isLoading: false,
};

export const DeleteOperation = Template.bind({});
DeleteOperation.args = {
open: true,
method: 'DELETE',
url: '/api/v1/namespaces/default/pods/example-pod',
body: '',
onClose: () => console.log('Dialog closed'),
onConfirm: () => console.log('Delete confirmed'),
isLoading: false,
};

export const PutUpdateOperation = Template.bind({});
PutUpdateOperation.args = {
open: true,
method: 'PUT',
url: '/api/v1/namespaces/default/pods/example-pod',
body: mockJsonBody,
onClose: () => console.log('Dialog closed'),
onConfirm: (editedBody) => console.log('Update confirmed:', editedBody),
isLoading: false,
};

export const LoadingState = Template.bind({});
LoadingState.args = {
open: true,
method: 'POST',
url: '/api/v1/namespaces/default/configmaps',
body: mockYamlBody,
onClose: () => console.log('Dialog closed'),
onConfirm: () => console.log('Confirmed'),
isLoading: true,
};

export const WithError = Template.bind({});
WithError.args = {
open: true,
method: 'POST',
url: '/api/v1/namespaces/default/configmaps',
body: mockYamlBody,
onClose: () => console.log('Dialog closed'),
onConfirm: () => console.log('Confirmed'),
isLoading: false,
error: 'Failed to create resource: ConfigMap already exists',
};

export const Empty = Template.bind({});
Empty.args = {
open: true,
method: 'GET',
url: '/api/v1/namespaces/default/pods',
body: '',
onClose: () => console.log('Dialog closed'),
onConfirm: () => console.log('Confirmed'),
isLoading: false,
};
68 changes: 68 additions & 0 deletions ai-assistant/src/components/common/LogsButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Meta, StoryFn } from '@storybook/react/types-6-0';
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Apache 2.0 license header. All source files in this repository should include the Apache 2.0 license header with 2025 copyright year, as established in other source files throughout the codebase.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import uses '@storybook/react/types-6-0' which is a Storybook v6-specific type path. While this exists in the codebase (app-catalog uses it), newer files in the repository use '@storybook/react' directly (see prometheus/src/components/Chart/Chart/chart.stories.tsx, app-catalog/src/components/charts/SettingsLink.stories.tsx). Consider using the modern import pattern for consistency with newer code, unless there's a specific reason to use the v6 type path.

Suggested change
import { Meta, StoryFn } from '@storybook/react/types-6-0';
import { Meta, StoryFn } from '@storybook/react';

Copilot uses AI. Check for mistakes.
import React from 'react';
import { TestContext } from '@kinvolk/headlamp-plugin/lib/testLib';
import LogsButton from './LogsButton';

export default {
title: 'components/common/LogsButton',
component: LogsButton,
decorators: [
(Story) => (
<TestContext>
<Story />
</TestContext>
),
],
} as Meta;

const mockLogs = `2025-02-09T10:15:30Z - INFO - Application started
2025-02-09T10:15:31Z - DEBUG - Initializing database connection
2025-02-09T10:15:32Z - DEBUG - Database connection established
2025-02-09T10:15:33Z - INFO - Server listening on port 8080
2025-02-09T10:15:40Z - INFO - Request received from 192.168.1.100
2025-02-09T10:15:41Z - DEBUG - Processing request...
2025-02-09T10:15:42Z - INFO - Response sent successfully`;

const Template: StoryFn<typeof LogsButton> = (args) => <LogsButton {...args} />;

export const Default = Template.bind({});
Default.args = {
logs: mockLogs,
resourceName: 'api-server',
resourceType: 'Deployment',
namespace: 'default',
containerName: 'api',
};

export const WithoutContainerName = Template.bind({});
WithoutContainerName.args = {
logs: mockLogs,
resourceName: 'nginx-pod',
resourceType: 'Pod',
namespace: 'production',
};

export const Empty = Template.bind({});
Empty.args = {
logs: '',
resourceName: 'empty-pod',
resourceType: 'Pod',
namespace: 'default',
};

export const WithoutMetadata = Template.bind({});
WithoutMetadata.args = {
logs: 'Simple log output without metadata',
};

export const LongLogs = Template.bind({});
LongLogs.args = {
logs: Array(100)
.fill(0)
.map((_, i) => `${new Date().toISOString()} - Line ${i + 1} of log output`)
.join('\n'),
resourceName: 'database',
resourceType: 'StatefulSet',
namespace: 'databases',
containerName: 'postgres',
};
Loading
Loading