Skip to content
Merged
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
1 change: 1 addition & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ dist/
# Storybook build outputs
.out
.storybook-out
storybook-static/

# vuepress build output
.vuepress/dist
Expand Down
9 changes: 9 additions & 0 deletions frontend/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { StorybookConfig } from '@storybook/angular';

const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(ts)'],
addons: [],
framework: '@storybook/angular',
};

export default config;
15 changes: 15 additions & 0 deletions frontend/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { provideHttpClient } from '@angular/common/http';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideRouter } from '@angular/router';
import type { Preview } from '@storybook/angular';
import { applicationConfig } from '@storybook/angular';

const preview: Preview = {
decorators: [
applicationConfig({
providers: [provideAnimations(), provideHttpClient(), provideRouter([])],
}),
],
};

export default preview;
7 changes: 7 additions & 0 deletions frontend/.storybook/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["node"]
},
"include": ["../src/**/*.stories.ts", "../src/**/*.d.ts", "../src/polyfills.ts", "./preview.ts", "./main.ts"]
}
44 changes: 44 additions & 0 deletions frontend/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,50 @@
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"],
"exclude": ["**/node_modules/**"]
}
},
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
"compodoc": false,
"configDir": ".storybook",
"browserTarget": "rocketadmin:build",
"port": 6006,
"styles": [
"node_modules/@fontsource/noto-sans/300.css",
"node_modules/@fontsource/noto-sans/400.css",
"node_modules/@fontsource/noto-sans/500.css",
"node_modules/@fontsource/ibm-plex-mono/400.css",
"node_modules/@fontsource/ibm-plex-mono/500.css",
"node_modules/@material-symbols/font-400/outlined.css",
"src/custom-theme.scss",
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["node_modules/@brumeilde/ngx-theme/presets/material"]
}
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"compodoc": false,
"configDir": ".storybook",
"browserTarget": "rocketadmin:build",
"outputDir": "storybook-static",
"styles": [
"node_modules/@fontsource/noto-sans/300.css",
"node_modules/@fontsource/noto-sans/400.css",
"node_modules/@fontsource/noto-sans/500.css",
"node_modules/@fontsource/ibm-plex-mono/400.css",
"node_modules/@fontsource/ibm-plex-mono/500.css",
"node_modules/@material-symbols/font-400/outlined.css",
"src/custom-theme.scss",
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": ["node_modules/@brumeilde/ngx-theme/presets/material"]
}
}
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"e2e": "ng e2e",
"analyze": "webpack-bundle-analyzer dist/rocketadmin/stats.json",
"build:stats": "node scripts/update-version.js && ng build --stats-json",
"update-version": "node scripts/update-version.js"
"update-version": "node scripts/update-version.js",
"storybook": "ng run rocketadmin:storybook",
"storybook:build": "ng run rocketadmin:build-storybook"
},
"private": true,
"dependencies": {
Expand Down Expand Up @@ -78,16 +80,19 @@
"@angular/compiler-cli": "~20.3.16",
"@angular/language-service": "~20.3.16",
"@sentry-internal/rrweb": "^2.16.0",
"@storybook/angular": "^10.2.14",
"@types/node": "^22.10.2",
"@vitest/browser": "^3.1.1",
"jsdom": "^27.4.0",
"playwright": "^1.57.0",
"storybook": "^10.2.14",
"ts-node": "~10.9.2",
"typescript": "~5.9.3",
"vitest": "^3.1.1"
},
"resolutions": {
"mermaid": "^11.10.0"
"mermaid": "^11.10.0",
"webpack": "5.104.1"
},
"packageManager": "yarn@1.22.22"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { applicationConfig, type Meta, type StoryObj } from '@storybook/angular';
import { Angulartics2 } from 'angulartics2';
import { of } from 'rxjs';
import { CompanyService } from 'src/app/services/company.service';
import { InviteMemberDialogComponent } from './invite-member-dialog.component';

const mockCompanyService: Partial<CompanyService> = {
inviteCompanyMember: () => of(null as any),
};

const mockAngulartics: Partial<Angulartics2> = {
eventTrack: { next: () => {} } as any,
};

const meta: Meta<InviteMemberDialogComponent> = {
title: 'Dialogs/InviteMember',
component: InviteMemberDialogComponent,
decorators: [
applicationConfig({
providers: [
{ provide: MatDialogRef, useValue: { close: () => {} } },
{
provide: MAT_DIALOG_DATA,
useValue: {
id: 'company-1',
connections: [
{
title: 'Production DB',
isTestConnection: false,
groups: [
{ id: 'group-1', title: 'Admins' },
{ id: 'group-2', title: 'Readers' },
],
},
{
title: 'Test DB',
isTestConnection: true,
groups: [{ id: 'group-3', title: 'Testers' }],
},
],
},
},
{ provide: CompanyService, useValue: mockCompanyService },
{ provide: Angulartics2, useValue: mockAngulartics },
],
}),
],
};

export default meta;
type Story = StoryObj<InviteMemberDialogComponent>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { applicationConfig, type Meta, type StoryObj } from '@storybook/angular';
import { Angulartics2 } from 'angulartics2';
import { of } from 'rxjs';
import { ConnectionsService } from 'src/app/services/connections.service';
import { DbConnectionDeleteDialogComponent } from './db-connection-delete-dialog.component';

const mockConnectionsService: Partial<ConnectionsService> = {
deleteConnection: () => of(null as any),
};

const mockRouter: Partial<Router> = {
navigate: () => Promise.resolve(true),
};

const mockAngulartics: Partial<Angulartics2> = {
eventTrack: { next: () => {} } as any,
};

const meta: Meta<DbConnectionDeleteDialogComponent> = {
title: 'Dialogs/DbConnectionDelete',
component: DbConnectionDeleteDialogComponent,
decorators: [
applicationConfig({
providers: [
{ provide: MatDialogRef, useValue: { close: () => {} } },
{
provide: MAT_DIALOG_DATA,
useValue: {
id: 'conn-1',
title: 'My PostgreSQL Database',
database: 'test_db',
},
},
{ provide: ConnectionsService, useValue: mockConnectionsService },
{ provide: Router, useValue: mockRouter },
{ provide: Angulartics2, useValue: mockAngulartics },
],
}),
],
};

export default meta;
type Story = StoryObj<DbConnectionDeleteDialogComponent>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { CassandraCredentialsFormComponent } from './cassandra-credentials-form.component';

const mockConnection = {
id: null,
database: 'test_keyspace',
title: 'Test Cassandra Connection',
host: 'localhost',
port: '9042',
sid: null,
type: 'cassandra',
username: 'admin',
password: '',
ssh: false,
ssl: false,
cert: '',
masterEncryption: false,
azure_encryption: false,
connectionType: 'direct',
schema: '',
};

const meta: Meta<CassandraCredentialsFormComponent> = {
title: 'DB Credentials/Cassandra',
component: CassandraCredentialsFormComponent,
args: {
connection: mockConnection as any,
readonly: false,
submitting: false,
masterKey: '',
accessLevel: 'edit',
},
};

export default meta;
type Story = StoryObj<CassandraCredentialsFormComponent>;

export const Default: Story = {};

export const Readonly: Story = {
args: {
readonly: true,
},
};

export const Submitting: Story = {
args: {
submitting: true,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { ClickhouseCredentialsFormComponent } from './clickhouse-credentials-form.component';

const mockConnection = {
id: null,
database: 'default',
title: 'Test ClickHouse Connection',
host: 'localhost',
port: '8123',
sid: null,
type: 'clickhouse',
username: 'default',
password: '',
ssh: false,
ssl: false,
cert: '',
masterEncryption: false,
azure_encryption: false,
connectionType: 'direct',
schema: '',
};

const meta: Meta<ClickhouseCredentialsFormComponent> = {
title: 'DB Credentials/ClickHouse',
component: ClickhouseCredentialsFormComponent,
args: {
connection: mockConnection as any,
readonly: false,
submitting: false,
masterKey: '',
accessLevel: 'edit',
},
};

export default meta;
type Story = StoryObj<ClickhouseCredentialsFormComponent>;

export const Default: Story = {};

export const Readonly: Story = {
args: {
readonly: true,
},
};

export const Submitting: Story = {
args: {
submitting: true,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { Db2CredentialsFormComponent } from './db2-credentials-form.component';

const mockConnection = {
id: null,
database: 'test_db',
title: 'Test IBM DB2 Connection',
host: 'localhost',
port: '50000',
sid: null,
type: 'ibmdb2',
username: 'admin',
password: '',
ssh: false,
ssl: false,
cert: '',
masterEncryption: false,
azure_encryption: false,
connectionType: 'direct',
schema: '',
};

const meta: Meta<Db2CredentialsFormComponent> = {
title: 'DB Credentials/IBM DB2',
component: Db2CredentialsFormComponent,
args: {
connection: mockConnection as any,
readonly: false,
submitting: false,
masterKey: '',
accessLevel: 'edit',
},
};

export default meta;
type Story = StoryObj<Db2CredentialsFormComponent>;

export const Default: Story = {};

export const Readonly: Story = {
args: {
readonly: true,
},
};

export const Submitting: Story = {
args: {
submitting: true,
},
};
Loading
Loading