[BEEEP] [PM-10132] Upgrade storybook to v8 (#10288)
Upgrade storybook to version v8 which is a major upgrade. Storybook provides an upgrade wizard which did most of the work. - Ran npx storybook upgrade. - Manually updated `remark-gfm` since the newer mdx requires v 4. - Migrated all old stories still using `Story` to `StoryObj`.
This commit is contained in:
parent
92f87dad9a
commit
604e22334a
|
@ -1,3 +1,4 @@
|
|||
import { dirname, join } from "path";
|
||||
import { StorybookConfig } from "@storybook/angular";
|
||||
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
|
||||
import remarkGfm from "remark-gfm";
|
||||
|
@ -20,11 +21,11 @@ const config: StorybookConfig = {
|
|||
"../bitwarden_license/bit-web/src/**/*.stories.@(js|jsx|ts|tsx)",
|
||||
],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-a11y",
|
||||
"@storybook/addon-designs",
|
||||
"@storybook/addon-interactions",
|
||||
getAbsolutePath("@storybook/addon-links"),
|
||||
getAbsolutePath("@storybook/addon-essentials"),
|
||||
getAbsolutePath("@storybook/addon-a11y"),
|
||||
getAbsolutePath("@storybook/addon-designs"),
|
||||
getAbsolutePath("@storybook/addon-interactions"),
|
||||
{
|
||||
name: "@storybook/addon-docs",
|
||||
options: {
|
||||
|
@ -37,7 +38,7 @@ const config: StorybookConfig = {
|
|||
},
|
||||
],
|
||||
framework: {
|
||||
name: "@storybook/angular",
|
||||
name: getAbsolutePath("@storybook/angular"),
|
||||
options: {},
|
||||
},
|
||||
core: {
|
||||
|
@ -53,9 +54,12 @@ const config: StorybookConfig = {
|
|||
}
|
||||
return config;
|
||||
},
|
||||
docs: {
|
||||
autodocs: true,
|
||||
},
|
||||
docs: {},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
// Recommended for mono-repositories
|
||||
function getAbsolutePath(value: string): any {
|
||||
return dirname(require.resolve(join(value, "package.json")));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { addons } from "@storybook/addons";
|
||||
import { addons } from "@storybook/manager-api";
|
||||
import { create } from "@storybook/theming/create";
|
||||
|
||||
const lightTheme = create({
|
||||
|
|
|
@ -92,7 +92,6 @@ const preview: Preview = {
|
|||
},
|
||||
},
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
|
@ -107,6 +106,7 @@ const preview: Preview = {
|
|||
},
|
||||
docs: { source: { type: "dynamic", excludeDecorators: true } },
|
||||
},
|
||||
tags: ["autodocs"],
|
||||
};
|
||||
|
||||
export default preview;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { importProvidersFrom } from "@angular/core";
|
||||
import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
import { applicationConfig, Meta, moduleMetadata, StoryObj } from "@storybook/angular";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import {
|
||||
|
@ -55,6 +55,9 @@ export default {
|
|||
},
|
||||
} as Meta;
|
||||
|
||||
// TODO: This is a workaround since this story does weird things.
|
||||
type Story = StoryObj<any>;
|
||||
|
||||
const actionsData = {
|
||||
onValueChanged: action("onValueChanged"),
|
||||
onSubmit: action("onSubmit"),
|
||||
|
@ -99,9 +102,8 @@ const itemsFactory = (n: number, type: AccessItemType) => {
|
|||
const sampleMembers = itemsFactory(10, AccessItemType.Member);
|
||||
const sampleGroups = itemsFactory(6, AccessItemType.Group);
|
||||
|
||||
const StandaloneAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
||||
args: AccessSelectorComponent,
|
||||
) => ({
|
||||
// TODO: These renders are badly handled but storybook has made it more difficult to use multiple renders in a single story.
|
||||
const StandaloneAccessSelectorRender = (args: any) => ({
|
||||
props: {
|
||||
items: [],
|
||||
valueChanged: actionsData.onValueChanged,
|
||||
|
@ -109,25 +111,23 @@ const StandaloneAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
|||
...args,
|
||||
},
|
||||
template: `
|
||||
<bit-access-selector
|
||||
(ngModelChange)="valueChanged($event)"
|
||||
[ngModel]="initialValue"
|
||||
[items]="items"
|
||||
[disabled]="disabled"
|
||||
[columnHeader]="columnHeader"
|
||||
[showGroupColumn]="showGroupColumn"
|
||||
[selectorLabelText]="selectorLabelText"
|
||||
[selectorHelpText]="selectorHelpText"
|
||||
[emptySelectionText]="emptySelectionText"
|
||||
[permissionMode]="permissionMode"
|
||||
[showMemberRoles]="showMemberRoles"
|
||||
></bit-access-selector>
|
||||
`,
|
||||
<bit-access-selector
|
||||
(ngModelChange)="valueChanged($event)"
|
||||
[ngModel]="initialValue"
|
||||
[items]="items"
|
||||
[disabled]="disabled"
|
||||
[columnHeader]="columnHeader"
|
||||
[showGroupColumn]="showGroupColumn"
|
||||
[selectorLabelText]="selectorLabelText"
|
||||
[selectorHelpText]="selectorHelpText"
|
||||
[emptySelectionText]="emptySelectionText"
|
||||
[permissionMode]="permissionMode"
|
||||
[showMemberRoles]="showMemberRoles"
|
||||
></bit-access-selector>
|
||||
`,
|
||||
});
|
||||
|
||||
const DialogAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
||||
args: AccessSelectorComponent,
|
||||
) => ({
|
||||
const DialogAccessSelectorRender = (args: any) => ({
|
||||
props: {
|
||||
items: [],
|
||||
valueChanged: actionsData.onValueChanged,
|
||||
|
@ -164,7 +164,7 @@ const DialogAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
|||
aria-label="Delete"></button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
`,
|
||||
`,
|
||||
});
|
||||
|
||||
const dialogAccessItems = itemsFactory(10, AccessItemType.Collection);
|
||||
|
@ -190,153 +190,115 @@ const memberCollectionAccessItems = itemsFactory(3, AccessItemType.Collection).c
|
|||
},
|
||||
]);
|
||||
|
||||
export const Dialog = DialogAccessSelectorTemplate.bind({});
|
||||
Dialog.args = {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
showGroupColumn: true,
|
||||
columnHeader: "Collection",
|
||||
selectorLabelText: "Select Collections",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No collections added",
|
||||
disabled: false,
|
||||
initialValue: [],
|
||||
items: dialogAccessItems,
|
||||
};
|
||||
Dialog.story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
storyDescription: `
|
||||
Example of an access selector for modifying the collections a member has access to inside of a dialog.
|
||||
`,
|
||||
},
|
||||
export const Dialog: Story = {
|
||||
args: {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
showGroupColumn: true,
|
||||
columnHeader: "Collection",
|
||||
selectorLabelText: "Select Collections",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No collections added",
|
||||
disabled: false,
|
||||
initialValue: [] as any[],
|
||||
items: dialogAccessItems,
|
||||
},
|
||||
render: DialogAccessSelectorRender,
|
||||
};
|
||||
|
||||
export const MemberCollectionAccess = StandaloneAccessSelectorTemplate.bind({});
|
||||
MemberCollectionAccess.args = {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
showGroupColumn: true,
|
||||
columnHeader: "Collection",
|
||||
selectorLabelText: "Select Collections",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No collections added",
|
||||
disabled: false,
|
||||
initialValue: [],
|
||||
items: memberCollectionAccessItems,
|
||||
};
|
||||
MemberCollectionAccess.story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
storyDescription: `
|
||||
Example of an access selector for modifying the collections a member has access to.
|
||||
Includes examples of a readonly group and member that cannot be edited.
|
||||
`,
|
||||
},
|
||||
export const MemberCollectionAccess: Story = {
|
||||
args: {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
showGroupColumn: true,
|
||||
columnHeader: "Collection",
|
||||
selectorLabelText: "Select Collections",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No collections added",
|
||||
disabled: false,
|
||||
initialValue: [],
|
||||
items: memberCollectionAccessItems,
|
||||
},
|
||||
render: StandaloneAccessSelectorRender,
|
||||
};
|
||||
|
||||
export const MemberGroupAccess = StandaloneAccessSelectorTemplate.bind({});
|
||||
MemberGroupAccess.args = {
|
||||
permissionMode: "readonly",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups",
|
||||
selectorLabelText: "Select Groups",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No groups added",
|
||||
disabled: false,
|
||||
initialValue: [{ id: "3g" }, { id: "0g" }],
|
||||
items: itemsFactory(4, AccessItemType.Group).concat([
|
||||
{
|
||||
id: "admin",
|
||||
type: AccessItemType.Group,
|
||||
listName: "Admin Group",
|
||||
labelName: "Admin Group",
|
||||
},
|
||||
]),
|
||||
};
|
||||
MemberGroupAccess.story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
storyDescription: `
|
||||
Example of an access selector for selecting which groups an individual member belongs too.
|
||||
`,
|
||||
},
|
||||
export const MemberGroupAccess: Story = {
|
||||
args: {
|
||||
permissionMode: "readonly",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups",
|
||||
selectorLabelText: "Select Groups",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No groups added",
|
||||
disabled: false,
|
||||
initialValue: [{ id: "3g" }, { id: "0g" }],
|
||||
items: itemsFactory(4, AccessItemType.Group).concat([
|
||||
{
|
||||
id: "admin",
|
||||
type: AccessItemType.Group,
|
||||
listName: "Admin Group",
|
||||
labelName: "Admin Group",
|
||||
},
|
||||
]),
|
||||
},
|
||||
render: StandaloneAccessSelectorRender,
|
||||
};
|
||||
|
||||
export const GroupMembersAccess = StandaloneAccessSelectorTemplate.bind({});
|
||||
GroupMembersAccess.args = {
|
||||
permissionMode: "hidden",
|
||||
showMemberRoles: true,
|
||||
columnHeader: "Members",
|
||||
selectorLabelText: "Select Members",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No members added",
|
||||
disabled: false,
|
||||
initialValue: [{ id: "2m" }, { id: "0m" }],
|
||||
items: sampleMembers,
|
||||
};
|
||||
GroupMembersAccess.story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
storyDescription: `
|
||||
Example of an access selector for selecting which members belong to an specific group.
|
||||
`,
|
||||
},
|
||||
export const GroupMembersAccess: Story = {
|
||||
args: {
|
||||
permissionMode: "hidden",
|
||||
showMemberRoles: true,
|
||||
columnHeader: "Members",
|
||||
selectorLabelText: "Select Members",
|
||||
selectorHelpText: "Some helper text describing what this does",
|
||||
emptySelectionText: "No members added",
|
||||
disabled: false,
|
||||
initialValue: [{ id: "2m" }, { id: "0m" }],
|
||||
items: sampleMembers,
|
||||
},
|
||||
render: StandaloneAccessSelectorRender,
|
||||
};
|
||||
|
||||
export const CollectionAccess = StandaloneAccessSelectorTemplate.bind({});
|
||||
CollectionAccess.args = {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups/Members",
|
||||
selectorLabelText: "Select groups and members",
|
||||
selectorHelpText:
|
||||
"Permissions set for a member will replace permissions set by that member's group",
|
||||
emptySelectionText: "No members or groups added",
|
||||
disabled: false,
|
||||
initialValue: [
|
||||
{ id: "3g", permission: CollectionPermission.EditExceptPass },
|
||||
{ id: "0m", permission: CollectionPermission.View },
|
||||
],
|
||||
items: sampleGroups.concat(sampleMembers).concat([
|
||||
{
|
||||
id: "admin-group",
|
||||
type: AccessItemType.Group,
|
||||
listName: "Admin Group",
|
||||
labelName: "Admin Group",
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
id: "admin-member",
|
||||
type: AccessItemType.Member,
|
||||
listName: "Admin Member (admin@email.com)",
|
||||
labelName: "Admin Member",
|
||||
status: OrganizationUserStatusType.Confirmed,
|
||||
role: OrganizationUserType.Admin,
|
||||
email: "admin@email.com",
|
||||
readonly: true,
|
||||
},
|
||||
]),
|
||||
};
|
||||
GroupMembersAccess.story = {
|
||||
parameters: {
|
||||
docs: {
|
||||
storyDescription: `
|
||||
Example of an access selector for selecting which members/groups have access to a specific collection.
|
||||
`,
|
||||
},
|
||||
export const CollectionAccess: Story = {
|
||||
args: {
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups/Members",
|
||||
selectorLabelText: "Select groups and members",
|
||||
selectorHelpText:
|
||||
"Permissions set for a member will replace permissions set by that member's group",
|
||||
emptySelectionText: "No members or groups added",
|
||||
disabled: false,
|
||||
initialValue: [
|
||||
{ id: "3g", permission: CollectionPermission.EditExceptPass },
|
||||
{ id: "0m", permission: CollectionPermission.View },
|
||||
],
|
||||
items: sampleGroups.concat(sampleMembers).concat([
|
||||
{
|
||||
id: "admin-group",
|
||||
type: AccessItemType.Group,
|
||||
listName: "Admin Group",
|
||||
labelName: "Admin Group",
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
id: "admin-member",
|
||||
type: AccessItemType.Member,
|
||||
listName: "Admin Member (admin@email.com)",
|
||||
labelName: "Admin Member",
|
||||
status: OrganizationUserStatusType.Confirmed,
|
||||
role: OrganizationUserType.Admin,
|
||||
email: "admin@email.com",
|
||||
readonly: true,
|
||||
},
|
||||
]),
|
||||
},
|
||||
render: StandaloneAccessSelectorRender,
|
||||
};
|
||||
|
||||
const fb = new FormBuilder();
|
||||
|
||||
const ReactiveFormAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
||||
args: AccessSelectorComponent,
|
||||
) => ({
|
||||
const ReactiveFormAccessSelectorRender = (args: any) => ({
|
||||
props: {
|
||||
items: [],
|
||||
onSubmit: actionsData.onSubmit,
|
||||
|
@ -344,30 +306,32 @@ const ReactiveFormAccessSelectorTemplate: Story<AccessSelectorComponent> = (
|
|||
},
|
||||
template: `
|
||||
<form [formGroup]="formObj" (ngSubmit)="onSubmit(formObj.controls.formItems.value)">
|
||||
<bit-access-selector
|
||||
formControlName="formItems"
|
||||
[items]="items"
|
||||
[columnHeader]="columnHeader"
|
||||
[selectorLabelText]="selectorLabelText"
|
||||
[selectorHelpText]="selectorHelpText"
|
||||
[emptySelectionText]="emptySelectionText"
|
||||
[permissionMode]="permissionMode"
|
||||
[showMemberRoles]="showMemberRoles"
|
||||
></bit-access-selector>
|
||||
<button type="submit" bitButton buttonType="primary" class="tw-mt-5">Submit</button>
|
||||
<bit-access-selector
|
||||
formControlName="formItems"
|
||||
[items]="items"
|
||||
[columnHeader]="columnHeader"
|
||||
[selectorLabelText]="selectorLabelText"
|
||||
[selectorHelpText]="selectorHelpText"
|
||||
[emptySelectionText]="emptySelectionText"
|
||||
[permissionMode]="permissionMode"
|
||||
[showMemberRoles]="showMemberRoles"
|
||||
></bit-access-selector>
|
||||
<button type="submit" bitButton buttonType="primary" class="tw-mt-5">Submit</button>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
|
||||
export const ReactiveForm = ReactiveFormAccessSelectorTemplate.bind({});
|
||||
ReactiveForm.args = {
|
||||
formObj: fb.group({ formItems: [[{ id: "1g" }]] }),
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups/Members",
|
||||
selectorLabelText: "Select groups and members",
|
||||
selectorHelpText:
|
||||
"Permissions set for a member will replace permissions set by that member's group",
|
||||
emptySelectionText: "No members or groups added",
|
||||
items: sampleGroups.concat(sampleMembers),
|
||||
export const ReactiveForm: Story = {
|
||||
args: {
|
||||
formObj: fb.group({ formItems: [[{ id: "1g" }]] }),
|
||||
permissionMode: "edit",
|
||||
showMemberRoles: false,
|
||||
columnHeader: "Groups/Members",
|
||||
selectorLabelText: "Select groups and members",
|
||||
selectorHelpText:
|
||||
"Permissions set for a member will replace permissions set by that member's group",
|
||||
emptySelectionText: "No members or groups added",
|
||||
items: sampleGroups.concat(sampleMembers),
|
||||
},
|
||||
render: ReactiveFormAccessSelectorRender,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { importProvidersFrom } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
import { delay, of, startWith } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
|
@ -26,60 +26,61 @@ export default {
|
|||
],
|
||||
}),
|
||||
],
|
||||
render: (args) => ({
|
||||
props: {
|
||||
createServiceAccount: false,
|
||||
importSecrets$: of(false),
|
||||
createSecret: false,
|
||||
createProject: false,
|
||||
...args,
|
||||
},
|
||||
template: `
|
||||
<app-onboarding title="Get started">
|
||||
<app-onboarding-task
|
||||
[title]="'createMachineAccount' | i18n"
|
||||
icon="bwi-cli"
|
||||
[completed]="createServiceAccount"
|
||||
>
|
||||
<span>
|
||||
{{ "downloadThe" | i18n }} <a bitLink routerLink="">{{ "smCLI" | i18n }}</a>
|
||||
</span>
|
||||
</app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'createProject' | i18n"
|
||||
icon="bwi-collection"
|
||||
[completed]="createProject"
|
||||
></app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'importSecrets' | i18n"
|
||||
icon="bwi-download"
|
||||
[completed]="importSecrets$ | async"
|
||||
></app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'createSecret' | i18n"
|
||||
icon="bwi-key"
|
||||
[completed]="createSecret"
|
||||
></app-onboarding-task>
|
||||
</app-onboarding>
|
||||
`,
|
||||
}),
|
||||
} as Meta;
|
||||
|
||||
const Template: Story = (args) => ({
|
||||
props: {
|
||||
createServiceAccount: false,
|
||||
importSecrets$: of(false),
|
||||
createSecret: false,
|
||||
createProject: false,
|
||||
...args,
|
||||
type Story = StoryObj<OnboardingComponent>;
|
||||
|
||||
export const Empty: Story = {};
|
||||
|
||||
export const Partial = {
|
||||
args: {
|
||||
createServiceAccount: true,
|
||||
createProject: true,
|
||||
},
|
||||
template: `
|
||||
<app-onboarding title="Get started">
|
||||
<app-onboarding-task
|
||||
[title]="'createMachineAccount' | i18n"
|
||||
icon="bwi-cli"
|
||||
[completed]="createServiceAccount"
|
||||
>
|
||||
<span>
|
||||
{{ "downloadThe" | i18n }} <a bitLink routerLink="">{{ "smCLI" | i18n }}</a>
|
||||
</span>
|
||||
</app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'createProject' | i18n"
|
||||
icon="bwi-collection"
|
||||
[completed]="createProject"
|
||||
></app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'importSecrets' | i18n"
|
||||
icon="bwi-download"
|
||||
[completed]="importSecrets$ | async"
|
||||
></app-onboarding-task>
|
||||
<app-onboarding-task
|
||||
[title]="'createSecret' | i18n"
|
||||
icon="bwi-key"
|
||||
[completed]="createSecret"
|
||||
></app-onboarding-task>
|
||||
</app-onboarding>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Empty = Template.bind({});
|
||||
|
||||
export const Partial = Template.bind({});
|
||||
Partial.args = {
|
||||
...Template.args,
|
||||
createServiceAccount: true,
|
||||
createProject: true,
|
||||
};
|
||||
|
||||
export const Full = Template.bind({});
|
||||
Full.args = {
|
||||
...Template.args,
|
||||
createServiceAccount: true,
|
||||
createProject: true,
|
||||
createSecret: true,
|
||||
importSecrets$: of(true).pipe(delay(0), startWith(false)),
|
||||
export const Full = {
|
||||
args: {
|
||||
createServiceAccount: true,
|
||||
createProject: true,
|
||||
createSecret: true,
|
||||
importSecrets$: of(true).pipe(delay(0), startWith(false)),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { importProvidersFrom } from "@angular/core";
|
||||
import { RouterTestingModule } from "@angular/router/testing";
|
||||
import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { BadgeModule, IconModule } from "@bitwarden/components";
|
||||
|
@ -32,18 +32,18 @@ export default {
|
|||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ReportCardComponent> = (args: ReportCardComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
type Story = StoryObj<ReportCardComponent>;
|
||||
|
||||
export const Enabled = Template.bind({});
|
||||
export const Enabled: Story = {};
|
||||
|
||||
export const RequiresPremium = Template.bind({});
|
||||
RequiresPremium.args = {
|
||||
variant: ReportVariant.RequiresPremium,
|
||||
export const RequiresPremium: Story = {
|
||||
args: {
|
||||
variant: ReportVariant.RequiresPremium,
|
||||
},
|
||||
};
|
||||
|
||||
export const RequiresUpgrade = Template.bind({});
|
||||
RequiresUpgrade.args = {
|
||||
variant: ReportVariant.RequiresUpgrade,
|
||||
export const RequiresUpgrade: Story = {
|
||||
args: {
|
||||
variant: ReportVariant.RequiresUpgrade,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { importProvidersFrom } from "@angular/core";
|
||||
import { RouterTestingModule } from "@angular/router/testing";
|
||||
import { Meta, Story, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { BadgeModule, IconModule } from "@bitwarden/components";
|
||||
|
@ -34,8 +34,6 @@ export default {
|
|||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ReportListComponent> = (args: ReportListComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
type Story = StoryObj<ReportListComponent>;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
export const Default: Story = {};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular";
|
||||
import { of } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
|
@ -47,9 +47,6 @@ export default {
|
|||
],
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<PremiumBadgeComponent> = (args: PremiumBadgeComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
type Story = StoryObj<PremiumBadgeComponent>;
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
Primary.args = {};
|
||||
export const Primary: Story = {};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { importProvidersFrom } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { applicationConfig, Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
import { applicationConfig, Meta, moduleMetadata, StoryObj } from "@storybook/angular";
|
||||
import { BehaviorSubject, of } from "rxjs";
|
||||
|
||||
import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
|
||||
|
@ -118,138 +118,136 @@ export default {
|
|||
argTypes: { onEvent: { action: "onEvent" } },
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<VaultItemsComponent> = (args: VaultItemsComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
type Story = StoryObj<VaultItemsComponent>;
|
||||
|
||||
export const Individual = Template.bind({});
|
||||
Individual.args = {
|
||||
ciphers,
|
||||
collections: [],
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
cloneableOrganizationCiphers: false,
|
||||
export const Individual: Story = {
|
||||
args: {
|
||||
ciphers,
|
||||
collections: [],
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const IndividualDisabled = Template.bind({});
|
||||
IndividualDisabled.args = {
|
||||
ciphers,
|
||||
collections: [],
|
||||
disabled: true,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
cloneableOrganizationCiphers: false,
|
||||
export const IndividualDisabled: Story = {
|
||||
args: {
|
||||
ciphers,
|
||||
collections: [],
|
||||
disabled: true,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const IndividualTrash = Template.bind({});
|
||||
IndividualTrash.args = {
|
||||
ciphers: deletedCiphers,
|
||||
collections: [],
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: true,
|
||||
useEvents: false,
|
||||
cloneableOrganizationCiphers: false,
|
||||
export const IndividualTrash: Story = {
|
||||
args: {
|
||||
ciphers: deletedCiphers,
|
||||
collections: [],
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: true,
|
||||
useEvents: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const IndividualTopLevelCollection = Template.bind({});
|
||||
IndividualTopLevelCollection.args = {
|
||||
ciphers: [],
|
||||
collections,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
cloneableOrganizationCiphers: false,
|
||||
export const IndividualTopLevelCollection: Story = {
|
||||
args: {
|
||||
ciphers: [],
|
||||
collections,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const IndividualSecondLevelCollection = Template.bind({});
|
||||
IndividualSecondLevelCollection.args = {
|
||||
ciphers,
|
||||
collections,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
cloneableOrganizationCiphers: false,
|
||||
export const IndividualSecondLevelCollection: Story = {
|
||||
args: {
|
||||
ciphers,
|
||||
collections,
|
||||
showOwner: true,
|
||||
showCollections: false,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: true,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const OrganizationVault = Template.bind({});
|
||||
OrganizationVault.args = {
|
||||
ciphers: organizationOnlyCiphers,
|
||||
collections: [],
|
||||
showOwner: false,
|
||||
showCollections: true,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
cloneableOrganizationCiphers: true,
|
||||
export const OrganizationVault: Story = {
|
||||
args: {
|
||||
ciphers: organizationOnlyCiphers,
|
||||
collections: [],
|
||||
showOwner: false,
|
||||
showCollections: true,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const OrganizationTrash = Template.bind({});
|
||||
OrganizationTrash.args = {
|
||||
ciphers: deletedOrganizationOnlyCiphers,
|
||||
collections: [],
|
||||
showOwner: false,
|
||||
showCollections: true,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: true,
|
||||
useEvents: true,
|
||||
cloneableOrganizationCiphers: true,
|
||||
export const OrganizationTrash: Story = {
|
||||
args: {
|
||||
ciphers: deletedOrganizationOnlyCiphers,
|
||||
collections: [],
|
||||
showOwner: false,
|
||||
showCollections: true,
|
||||
showGroups: false,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: true,
|
||||
useEvents: true,
|
||||
},
|
||||
};
|
||||
|
||||
const unassignedCollection = new CollectionAdminView();
|
||||
unassignedCollection.id = Unassigned;
|
||||
unassignedCollection.name = "Unassigned";
|
||||
export const OrganizationTopLevelCollection = Template.bind({});
|
||||
OrganizationTopLevelCollection.args = {
|
||||
ciphers: [],
|
||||
collections: collections.concat(unassignedCollection),
|
||||
showOwner: false,
|
||||
showCollections: false,
|
||||
showGroups: true,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
cloneableOrganizationCiphers: true,
|
||||
export const OrganizationTopLevelCollection: Story = {
|
||||
args: {
|
||||
ciphers: [],
|
||||
collections: collections.concat(unassignedCollection),
|
||||
showOwner: false,
|
||||
showCollections: false,
|
||||
showGroups: true,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const OrganizationSecondLevelCollection = Template.bind({});
|
||||
OrganizationSecondLevelCollection.args = {
|
||||
ciphers: organizationOnlyCiphers,
|
||||
collections,
|
||||
showOwner: false,
|
||||
showCollections: false,
|
||||
showGroups: true,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
cloneableOrganizationCiphers: true,
|
||||
export const OrganizationSecondLevelCollection: Story = {
|
||||
args: {
|
||||
ciphers: organizationOnlyCiphers,
|
||||
collections,
|
||||
showOwner: false,
|
||||
showCollections: false,
|
||||
showGroups: true,
|
||||
showPremiumFeatures: true,
|
||||
showBulkMove: false,
|
||||
showBulkTrashOptions: false,
|
||||
useEvents: true,
|
||||
},
|
||||
};
|
||||
|
||||
function createCipherView(i: number, deleted = false): CipherView {
|
||||
|
|
|
@ -48,7 +48,7 @@ export const Premium: Story = {
|
|||
args: {
|
||||
bannerType: "premium",
|
||||
},
|
||||
render: (args: BannerComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-banner [bannerType]="bannerType" (onClose)="onClose($event)" [showClose]=showClose>
|
||||
|
@ -93,7 +93,7 @@ export const HideClose: Story = {
|
|||
|
||||
export const Stacked: Story = {
|
||||
args: {},
|
||||
render: (args: BannerComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-banner bannerType="premium" (onClose)="onClose($event)">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FormsModule } from "@angular/forms";
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
|
||||
import { getAllByRole, userEvent } from "@storybook/testing-library";
|
||||
import { getAllByRole, userEvent } from "@storybook/test";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
|
@ -40,7 +40,7 @@ export const Default: Story = {
|
|||
...args,
|
||||
},
|
||||
template: /* html */ `
|
||||
<bit-chip-select
|
||||
<bit-chip-select
|
||||
placeholderText="Folder"
|
||||
placeholderIcon="bwi-folder"
|
||||
[options]="options"
|
||||
|
@ -138,7 +138,7 @@ export const Disabled: Story = {
|
|||
...args,
|
||||
},
|
||||
template: /* html */ `
|
||||
<bit-chip-select
|
||||
<bit-chip-select
|
||||
placeholderText="Folder"
|
||||
placeholderIcon="bwi-folder"
|
||||
[options]="options"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { RouterTestingModule } from "@angular/router/testing";
|
||||
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
|
||||
import { userEvent } from "@storybook/testing-library";
|
||||
import { userEvent } from "@storybook/test";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
|
|
|
@ -69,8 +69,7 @@ export const WithoutIcon: Story = {
|
|||
};
|
||||
|
||||
export const WithoutRoute: Story = {
|
||||
render: (args: NavItemComponent) => ({
|
||||
props: args,
|
||||
render: () => ({
|
||||
template: `
|
||||
<bit-nav-item text="Hello World" icon="bwi-collection"></bit-nav-item>
|
||||
`,
|
||||
|
@ -78,7 +77,7 @@ export const WithoutRoute: Story = {
|
|||
};
|
||||
|
||||
export const WithChildButtons: Story = {
|
||||
render: (args: NavItemComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-nav-item text="Hello World" [route]="['']" icon="bwi-collection">
|
||||
|
@ -104,7 +103,7 @@ export const WithChildButtons: Story = {
|
|||
};
|
||||
|
||||
export const MultipleItemsWithDivider: Story = {
|
||||
render: (args: NavItemComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-nav-item text="Hello World" icon="bwi-collection"></bit-nav-item>
|
||||
|
@ -117,7 +116,7 @@ export const MultipleItemsWithDivider: Story = {
|
|||
};
|
||||
|
||||
export const ForceActiveStyles: Story = {
|
||||
render: (args: NavItemComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-nav-item text="First Nav" icon="bwi-collection"></bit-nav-item>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
{/* Iconography.stories.mdx */}
|
||||
|
||||
import { Meta } from "@storybook/addon-docs";
|
||||
|
||||
<Meta title="Documentation/Icons" />
|
||||
|
|
|
@ -8,13 +8,7 @@ import {
|
|||
componentWrapperDecorator,
|
||||
moduleMetadata,
|
||||
} from "@storybook/angular";
|
||||
import {
|
||||
userEvent,
|
||||
getAllByRole,
|
||||
getByRole,
|
||||
getByLabelText,
|
||||
fireEvent,
|
||||
} from "@storybook/testing-library";
|
||||
import { userEvent, getAllByRole, getByRole, getByLabelText, fireEvent } from "@storybook/test";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
|
||||
|
@ -126,14 +120,14 @@ export const MenuOpen: Story = {
|
|||
|
||||
export const DefaultDialogOpen: Story = {
|
||||
...Default,
|
||||
play: (context) => {
|
||||
play: async (context) => {
|
||||
const canvas = context.canvasElement;
|
||||
const dialogButton = getByRole(canvas, "button", {
|
||||
name: "Open Dialog",
|
||||
});
|
||||
|
||||
// workaround for userEvent not firing in FF https://github.com/testing-library/user-event/issues/1075
|
||||
fireEvent.click(dialogButton);
|
||||
await fireEvent.click(dialogButton);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -151,14 +145,14 @@ export const PopoverOpen: Story = {
|
|||
|
||||
export const SimpleDialogOpen: Story = {
|
||||
...Default,
|
||||
play: (context) => {
|
||||
play: async (context) => {
|
||||
const canvas = context.canvasElement;
|
||||
const submitButton = getByRole(canvas, "button", {
|
||||
name: "Submit",
|
||||
});
|
||||
|
||||
// workaround for userEvent not firing in FF https://github.com/testing-library/user-event/issues/1075
|
||||
fireEvent.click(submitButton);
|
||||
await fireEvent.click(submitButton);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ export const ContentTabs: Story = {
|
|||
};
|
||||
|
||||
export const NavigationTabs: Story = {
|
||||
render: (args: TabGroupComponent) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-tab-nav-bar label="Main">
|
||||
|
@ -126,7 +126,7 @@ export const NavigationTabs: Story = {
|
|||
};
|
||||
|
||||
export const PreserveContentTabs: Story = {
|
||||
render: (args: any) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-tab-group label="Preserve Content Tabs" [preserveContent]="true" class="tw-text-main">
|
||||
|
@ -147,7 +147,7 @@ export const PreserveContentTabs: Story = {
|
|||
};
|
||||
|
||||
export const KeyboardNavigation: Story = {
|
||||
render: (args: any) => ({
|
||||
render: (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-tab-group label="Keyboard Navigation Tabs" class="tw-text-main">
|
||||
|
|
File diff suppressed because it is too large
Load Diff
28
package.json
28
package.json
|
@ -47,15 +47,15 @@
|
|||
"@electron/notarize": "2.4.0",
|
||||
"@electron/rebuild": "3.6.0",
|
||||
"@ngtools/webpack": "16.2.14",
|
||||
"@storybook/addon-a11y": "7.6.19",
|
||||
"@storybook/addon-actions": "7.6.19",
|
||||
"@storybook/addon-designs": "7.0.9",
|
||||
"@storybook/addon-essentials": "7.6.19",
|
||||
"@storybook/addon-interactions": "7.6.19",
|
||||
"@storybook/addon-links": "7.6.19",
|
||||
"@storybook/angular": "7.6.19",
|
||||
"@storybook/jest": "0.2.3",
|
||||
"@storybook/testing-library": "0.2.2",
|
||||
"@storybook/addon-a11y": "8.2.6",
|
||||
"@storybook/addon-actions": "8.2.6",
|
||||
"@storybook/addon-designs": "8.0.3",
|
||||
"@storybook/addon-essentials": "8.2.6",
|
||||
"@storybook/addon-interactions": "8.2.6",
|
||||
"@storybook/addon-links": "8.2.6",
|
||||
"@storybook/angular": "8.2.6",
|
||||
"@storybook/manager-api": "8.2.6",
|
||||
"@storybook/theming": "8.2.6",
|
||||
"@types/argon2-browser": "1.18.4",
|
||||
"@types/chrome": "0.0.262",
|
||||
"@types/firefox-webext-browser": "111.0.5",
|
||||
|
@ -76,7 +76,6 @@
|
|||
"@types/node-ipc": "9.2.3",
|
||||
"@types/papaparse": "5.3.14",
|
||||
"@types/proper-lockfile": "4.1.4",
|
||||
"@types/react": "16.14.60",
|
||||
"@types/retry": "0.12.5",
|
||||
"@types/zxcvbn": "4.4.4",
|
||||
"@typescript-eslint/eslint-plugin": "7.16.1",
|
||||
|
@ -127,14 +126,12 @@
|
|||
"prettier": "3.3.3",
|
||||
"prettier-plugin-tailwindcss": "0.6.5",
|
||||
"process": "0.11.10",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"regedit": "^3.0.3",
|
||||
"remark-gfm": "3.0.1",
|
||||
"remark-gfm": "4.0.0",
|
||||
"rimraf": "6.0.1",
|
||||
"sass": "1.74.1",
|
||||
"sass-loader": "14.2.1",
|
||||
"storybook": "7.6.19",
|
||||
"storybook": "8.2.6",
|
||||
"style-loader": "3.3.4",
|
||||
"tailwindcss": "3.4.3",
|
||||
"ts-jest": "29.2.2",
|
||||
|
@ -214,9 +211,6 @@
|
|||
},
|
||||
"replacestream": "4.0.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "16.14.60"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "prettier --cache --ignore-unknown --write",
|
||||
"*.ts": "eslint --cache --cache-strategy content --fix"
|
||||
|
|
Loading…
Reference in New Issue