added some styling and async createList action
This commit is contained in:
parent
64aed858ae
commit
b4e7e8b194
|
@ -1,5 +1,5 @@
|
|||
import { action, computed, observable, runInAction } from "mobx";
|
||||
import { RootStore } from "./RootStore";
|
||||
import { observable, action, computed } from "mobx";
|
||||
|
||||
export enum ApplicationStatus {
|
||||
Loading = "Loading",
|
||||
|
@ -26,7 +26,7 @@ export class AppStore {
|
|||
}
|
||||
|
||||
@action
|
||||
private setInitialState() {
|
||||
private setInitialState(): void {
|
||||
this.status = ApplicationStatus.CreateList;
|
||||
this.listTitle = null;
|
||||
this.items = [];
|
||||
|
@ -50,18 +50,27 @@ export class AppStore {
|
|||
}
|
||||
|
||||
@action
|
||||
public confirmListCreation(listTitle: string) {
|
||||
public async createList(listTitle: string): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
// Mock creating list
|
||||
setTimeout(() => {
|
||||
runInAction(() => {
|
||||
this.status = ApplicationStatus.CreateItems;
|
||||
this.listTitle = listTitle;
|
||||
resolve();
|
||||
});
|
||||
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
public addListItem(item: IFakeItem) {
|
||||
public addListItem(item: IFakeItem): void {
|
||||
this.items.push(item);
|
||||
}
|
||||
|
||||
@action
|
||||
public confirmItems() {
|
||||
public confirmItems(): void {
|
||||
this.status = ApplicationStatus.Completed;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@ export class ConfigStore {
|
|||
@action
|
||||
private loadConfigration() {
|
||||
this.isLoading = false;
|
||||
this.applicationTitle = "Default Application Title";
|
||||
this.allowImportantItems = true;
|
||||
this.rootStore.appStore.isLoadingConfiguration = false;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"description": { "default": "An example of a webpart using mobx for managing the application state" },
|
||||
"officeFabricIconFontName": "Page",
|
||||
"properties": {
|
||||
"description": "MobxTutorial"
|
||||
"ApplicationTitle": "Mobx Tutorial Title (change in webpart properties) 😎"
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -11,14 +11,21 @@ import MobxTutorialProvider from './components/MobxTutorialProvider';
|
|||
configure({ enforceActions: "always" });
|
||||
|
||||
export interface IMobxTutorialWebPartProps {
|
||||
description: string;
|
||||
ApplicationTitle: string;
|
||||
}
|
||||
|
||||
export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTutorialWebPartProps> {
|
||||
private readonly dependencies = { rootStore: new RootStore() };
|
||||
|
||||
public render(): void {
|
||||
protected onInit() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const { configStore } = this.dependencies.rootStore;
|
||||
configStore.setApplicationTitle(this.properties.ApplicationTitle);
|
||||
resolve();
|
||||
});
|
||||
|
||||
}
|
||||
public render(): void {
|
||||
const element: React.ReactElement<{}> = React.createElement(
|
||||
MobxTutorialProvider,
|
||||
{
|
||||
|
@ -30,7 +37,7 @@ export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTuto
|
|||
}
|
||||
|
||||
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
|
||||
if (propertyPath === "Application title") {
|
||||
if (propertyPath === "ApplicationTitle") {
|
||||
const { configStore } = this.dependencies.rootStore;
|
||||
configStore.setApplicationTitle(newValue);
|
||||
}
|
||||
|
@ -55,8 +62,8 @@ export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTuto
|
|||
{
|
||||
groupName: strings.BasicGroupName,
|
||||
groupFields: [
|
||||
PropertyPaneTextField('Application title', {
|
||||
label: strings.AppTitleFieldLabel
|
||||
PropertyPaneTextField('ApplicationTitle', {
|
||||
label: strings.AppTitleFieldLabel,
|
||||
})
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
export interface IMobxTutorialProps {
|
||||
description: string;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
import { inject, observer } from "mobx-react";
|
||||
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import * as React from 'react';
|
||||
import { AppStore } from '../../../stores/AppStore';
|
||||
import { Stores } from "../../../stores/RootStore";
|
||||
|
||||
export type ListCreatorStoreProps = {
|
||||
appStore: AppStore;
|
||||
};
|
||||
|
||||
export type ListCreatorProps = Partial<ListCreatorStoreProps>;
|
||||
export type ListCreatorState = {
|
||||
loading: boolean;
|
||||
errorMessage: string;
|
||||
listTitle: string;
|
||||
};
|
||||
|
||||
@inject(Stores.AppStore)
|
||||
@observer
|
||||
export class ListCreator extends React.Component<ListCreatorProps, ListCreatorState> {
|
||||
public state = {
|
||||
loading: false,
|
||||
errorMessage: undefined,
|
||||
listTitle: null
|
||||
};
|
||||
|
||||
public render(): React.ReactElement<ListCreatorProps> {
|
||||
const spinner = (<Spinner size={SpinnerSize.xSmall} label="Creating list ..." labelPosition="right" />);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TextField
|
||||
label="List title"
|
||||
errorMessage={this.state.errorMessage}
|
||||
onChange={this._onChangeListTitle}
|
||||
value={this.state.listTitle}
|
||||
/>
|
||||
|
||||
<PrimaryButton
|
||||
onClick={() => this.createList()}
|
||||
disabled={this.state.loading}
|
||||
>
|
||||
{this.state.loading ? spinner : "Create List"}
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public async createList() {
|
||||
if (this.state.listTitle && this.state.listTitle.length > 0) {
|
||||
this.setState({ ...this.state, loading: true, errorMessage: undefined });
|
||||
await this.props.appStore.createList("MOCK TITLE");
|
||||
this.setState({ ...this.state, loading: false });
|
||||
}
|
||||
else {
|
||||
this.setState({ ...this.state, errorMessage: "Required" });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private _onChangeListTitle = (ev: React.FormEvent<HTMLInputElement>, newValue?: string) => {
|
||||
if (newValue === "" && newValue.length === 0) {
|
||||
this.setState({ ...this.state, listTitle: newValue, errorMessage: "Required" });
|
||||
}
|
||||
else {
|
||||
this.setState({ ...this.state, listTitle: newValue });
|
||||
|
||||
}
|
||||
};
|
||||
}
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
.row {
|
||||
@include ms-Grid-row;
|
||||
@include ms-fontColor-white;
|
||||
background-color: $ms-color-themeDark;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
@ -24,17 +22,10 @@
|
|||
|
||||
.title {
|
||||
@include ms-font-xl;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.subTitle {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include ms-font-l;
|
||||
@include ms-fontColor-white;
|
||||
}
|
||||
|
||||
.button {
|
||||
|
|
|
@ -6,6 +6,8 @@ import { ConfigStore } from '../../../stores/ConfigStore';
|
|||
import { Stores } from '../../../stores/RootStore';
|
||||
import { FakeItemContainer } from './FakeItemContainer';
|
||||
import { ProgressIndicator } from './ProgressIndicator';
|
||||
import { ListCreator } from './ListCreator';
|
||||
import styles from './MobxTutorial.module.scss';
|
||||
|
||||
export type MobxTutorialStoreProps = {
|
||||
appStore: AppStore;
|
||||
|
@ -24,11 +26,24 @@ export class MobxTutorial extends React.Component<MobxTutorialProps, {}> {
|
|||
return (<Spinner size={SpinnerSize.large} label="Loading... please hodl" ariaLive="assertive" labelPosition="left" />);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{configStore.applicationTitle}</h1>
|
||||
<div className={styles.mobxTutorial}>
|
||||
|
||||
<div className={styles.row}>
|
||||
<div className={styles.title}>{configStore.applicationTitle}</div>
|
||||
<ProgressIndicator></ProgressIndicator>
|
||||
</div>
|
||||
|
||||
<div className={styles.row}>
|
||||
<div className={styles.subTitle}>1) Create List</div>
|
||||
<ListCreator></ListCreator>
|
||||
</div>
|
||||
|
||||
<div className={styles.row}>
|
||||
<div className={styles.subTitle}>2) Create Items</div>
|
||||
<FakeItemContainer></FakeItemContainer>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue