mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 14:53:33 +00:00
[EC-558] Reflecting async progress on buttons and forms (#3548)
* [EC-556] feat: convert button into component * [EC-556] feat: implement loading state * [EC-556] feat: remove loading from submit button * [EC-556] fix: add missing import * [EC-556] fix: disabling button using regular attribute * [EC-556] feat: implement bitFormButton * [EC-556] feat: use bitFormButton in submit button * [EC-556] fix: missing import * [EC-558] chore: rename file to match class name * [EC-558] feat: allow skipping bitButton on form buttons * [EC-558]: only show spinner on submit button * [EC-558] feat: add new bit async directive * [EC-558] feat: add functionToObservable util * [EC-558] feat: implement bitAction directive * [EC-558] refactor: simplify bitSubmit using functionToObservable * [EC-558] feat: connect bit action with form button * [EC-558] feat: execute function immediately to allow for form validation * [EC-558] feat: disable form on loading * [EC-558] chore: remove duplicate types * [EC-558] feat: move validation service to common * [EC-558] feat: add error handling using validation service * [EC-558] feat: add support for icon button * [EC-558] fix: icon button hover border styles * [EC-558] chore: refactor icon button story to show all styles * [EC-558] fix: better align loading spinner to middle * [EC-558] fix: simplify try catch * [EC-558] chore: reorganize async actions * [EC-558] chore: rename stories * [EC-558] docs: add documentation * [EC-558] feat: decouple buttons and form buttons * [EC-558] chore: rename button like abstraction * [EC-558] chore: remove null check * [EC-558] docs: add jsdocs to directives * [EC-558] fix: switch abs imports to relative * [EC-558] chore: add async actions module to web shared module * [EC-558] chore: remove unecessary null check * [EC-558] chore: apply suggestions from code review Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * [EC-558] fix: whitespaces * [EC-558] feat: dont disable form by default * [EC-558] fix: bug where form could be submit during a previous submit * [EC-558] feat: remove ability to disable form Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
This commit is contained in:
97
libs/components/src/async-actions/standalone.stories.ts
Normal file
97
libs/components/src/async-actions/standalone.stories.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
import { delay, of } from "rxjs";
|
||||
|
||||
import { ValidationService } from "@bitwarden/common/abstractions/validation.service";
|
||||
|
||||
import { ButtonModule } from "../button";
|
||||
import { IconButtonModule } from "../icon-button";
|
||||
|
||||
import { BitActionDirective } from "./bit-action.directive";
|
||||
|
||||
const template = `
|
||||
<button bitButton buttonType="primary" [bitAction]="action" class="tw-mr-2">
|
||||
Perform action
|
||||
</button>
|
||||
<button bitIconButton="bwi-trash" buttonType="danger" [bitAction]="action"></button>`;
|
||||
|
||||
@Component({
|
||||
template,
|
||||
selector: "app-promise-example",
|
||||
})
|
||||
class PromiseExampleComponent {
|
||||
action = async () => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
setTimeout(resolve, 2000);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@Component({
|
||||
template,
|
||||
selector: "app-observable-example",
|
||||
})
|
||||
class ObservableExampleComponent {
|
||||
action = () => {
|
||||
return of("fake observable").pipe(delay(2000));
|
||||
};
|
||||
}
|
||||
|
||||
@Component({
|
||||
template,
|
||||
selector: "app-rejected-promise-example",
|
||||
})
|
||||
class RejectedPromiseExampleComponent {
|
||||
action = async () => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
setTimeout(() => reject(new Error("Simulated error")), 2000);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
title: "Component Library/Async Actions/Standalone",
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
declarations: [
|
||||
BitActionDirective,
|
||||
PromiseExampleComponent,
|
||||
ObservableExampleComponent,
|
||||
RejectedPromiseExampleComponent,
|
||||
],
|
||||
imports: [ButtonModule, IconButtonModule],
|
||||
providers: [
|
||||
{
|
||||
provide: ValidationService,
|
||||
useValue: {
|
||||
showError: action("ValidationService.showError"),
|
||||
} as Partial<ValidationService>,
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
} as Meta;
|
||||
|
||||
const PromiseTemplate: Story<PromiseExampleComponent> = (args: PromiseExampleComponent) => ({
|
||||
props: args,
|
||||
template: `<app-promise-example></app-promise-example>`,
|
||||
});
|
||||
|
||||
export const UsingPromise = PromiseTemplate.bind({});
|
||||
|
||||
const ObservableTemplate: Story<ObservableExampleComponent> = (
|
||||
args: ObservableExampleComponent
|
||||
) => ({
|
||||
template: `<app-observable-example></app-observable-example>`,
|
||||
});
|
||||
|
||||
export const UsingObservable = ObservableTemplate.bind({});
|
||||
|
||||
const RejectedPromiseTemplate: Story<ObservableExampleComponent> = (
|
||||
args: ObservableExampleComponent
|
||||
) => ({
|
||||
template: `<app-rejected-promise-example></app-rejected-promise-example>`,
|
||||
});
|
||||
|
||||
export const RejectedPromise = RejectedPromiseTemplate.bind({});
|
||||
Reference in New Issue
Block a user