added components to display data (unfinished)

This commit is contained in:
Kemal S 2019-05-22 12:59:23 +02:00
parent 70df646e63
commit 64aed858ae
11 changed files with 108 additions and 24 deletions

View File

@ -2,6 +2,7 @@ import { RootStore } from "./RootStore";
import { observable, action, computed } from "mobx";
export enum ApplicationStatus {
Loading = "Loading",
CreateList = "Create List",
CreateItems = "Create Items",
Completed = "Completed"
@ -14,7 +15,8 @@ export interface IFakeItem {
export class AppStore {
@observable public isLoading: boolean;
@observable public isLoadingConfiguration: boolean;
@observable public isLoadingOtherStuff: boolean;
@observable public status: ApplicationStatus;
@observable public listTitle: string;
@observable public items: IFakeItem[];
@ -28,7 +30,8 @@ export class AppStore {
this.status = ApplicationStatus.CreateList;
this.listTitle = null;
this.items = [];
this.isLoading = true;
this.isLoadingConfiguration = true;
this.isLoadingOtherStuff = false;
}
@computed
@ -36,6 +39,16 @@ export class AppStore {
return `The current status is: ${this.status}`;
}
@computed
public get importantItems(): IFakeItem[] {
return this.items.filter(x => x.important);
}
@computed
public get isLoading(): boolean {
return this.isLoadingConfiguration || this.isLoadingOtherStuff;
}
@action
public confirmListCreation(listTitle: string) {
this.status = ApplicationStatus.CreateItems;

View File

@ -1,5 +1,5 @@
import { action, observable } from "mobx";
import { RootStore } from "./RootStore";
import { observable, action, runInAction } from "mobx";
export class ConfigStore {
@ -13,7 +13,7 @@ export class ConfigStore {
// Mock REST call for fetching configuration data, 5 seconds
setTimeout(() => {
this.loadConfigration();
}, 5000);
}, 1000);
}
@action
@ -26,9 +26,9 @@ export class ConfigStore {
@action
private loadConfigration() {
this.isLoading = false;
this.applicationTitle = "So cool man";
this.applicationTitle = "Default Application Title";
this.allowImportantItems = true;
this.rootStore.appStore.isLoading = false;
this.rootStore.appStore.isLoadingConfiguration = false;
}
@action

View File

@ -1,5 +1,5 @@
import { ConfigStore } from "./ConfigStore";
import { AppStore } from "./AppStore";
import { ConfigStore } from "./ConfigStore";
export enum Stores {
AppStore = "appStore",
@ -9,12 +9,9 @@ export enum Stores {
export class RootStore {
public readonly appStore: AppStore;
public readonly configStore: ConfigStore;
public readonly rootStore: RootStore;
constructor() {
this.rootStore = this;
this.configStore = new ConfigStore(this);
this.appStore = new AppStore(this);
}
}

View File

@ -5,7 +5,7 @@ import { configure } from "mobx";
import * as strings from 'MobxTutorialWebPartStrings';
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { IMobxTutorialProps } from './components/IMobxTutorialProps';
import { RootStore } from '../../stores/RootStore';
import MobxTutorialProvider from './components/MobxTutorialProvider';
configure({ enforceActions: "always" });
@ -15,16 +15,27 @@ export interface IMobxTutorialWebPartProps {
}
export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTutorialWebPartProps> {
private readonly dependencies = { rootStore: new RootStore() };
public render(): void {
const element: React.ReactElement<{}> = React.createElement(
MobxTutorialProvider,
{
stores: { ...this.dependencies.rootStore }
}
);
ReactDom.render(element, this.domElement);
}
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): void {
if (propertyPath === "Application title") {
const { configStore } = this.dependencies.rootStore;
configStore.setApplicationTitle(newValue);
}
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
@ -44,8 +55,8 @@ export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTuto
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
PropertyPaneTextField('Application title', {
label: strings.AppTitleFieldLabel
})
]
}

View File

@ -0,0 +1,22 @@
import * as React from 'react';
import { IFakeItem } from '../../../stores/AppStore';
export type DetailedFakeItemViewerProps = {
items: IFakeItem[];
};
export class DetailedFakeItemViewer extends React.Component<DetailedFakeItemViewerProps, {}> {
public state = {
items: []
};
public render(): React.ReactElement<DetailedFakeItemViewerProps> {
const { items } = this.props;
return (
<div>
<ul>{items.map(x => <li>{x.title} {x.important ? '!IMPORTANT' : null}</li>)}</ul>
</div>
);
}
}

View File

@ -0,0 +1,32 @@
import { inject, observer } from "mobx-react";
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import * as React from 'react';
import { AppStore } from "../../../stores/AppStore";
import { Stores } from '../../../stores/RootStore';
import { DetailedFakeItemViewer } from "./DetailedFakeItemViewer";
export type FakeItemContainerStoreProps = {
appStore: AppStore;
};
export type FakeItemContainerOwnProps = {};
export type FakeItemContainerProps = Partial<FakeItemContainerStoreProps> & FakeItemContainerOwnProps;
@inject(Stores.AppStore)
@observer
export class FakeItemContainer extends React.Component<FakeItemContainerProps, {}> {
public render(): React.ReactElement<FakeItemContainerProps> {
const { appStore } = this.props;
return (
<div>
<PrimaryButton
text="Add Fake Item"
onClick={() => { appStore.addListItem({ title: "dsf", important: true }); }}
allowDisabledFocus={true}
/>
Count items: {appStore.items.length} | Count important items: {appStore.importantItems.length}
<DetailedFakeItemViewer items={appStore.items}></DetailedFakeItemViewer>
</div>
);
}
}

View File

@ -1,25 +1,33 @@
import { inject, observer } from 'mobx-react';
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
import * as React from 'react';
import { AppStore } from '../../../stores/AppStore';
import { ConfigStore } from '../../../stores/ConfigStore';
import { Stores } from '../../../stores/RootStore';
import { FakeItemContainer } from './FakeItemContainer';
import { ProgressIndicator } from './ProgressIndicator';
export type MobxTutorialStoreProps = {
appStore: AppStore;
configStore: ConfigStore;
};
export type MobxTutorialProps = Partial<MobxTutorialStoreProps>;
@inject(Stores.AppStore)
@inject(Stores.AppStore, Stores.ConfigurationStore)
@observer
export class MobxTutorial extends React.Component<MobxTutorialProps, {}> {
public render(): React.ReactElement<MobxTutorialProps> {
const { appStore } = this.props;
const { appStore, configStore } = this.props;
if (appStore.isLoading)
return (<Spinner size={SpinnerSize.large} label="Loading... please hodl" ariaLive="assertive" labelPosition="left" />);
return (
<div>
{appStore.isLoading ? "LOADING" : null}
<h1>{configStore.applicationTitle}</h1>
<ProgressIndicator></ProgressIndicator>
<FakeItemContainer></FakeItemContainer>
</div>
);
}

View File

@ -1,14 +1,16 @@
import { Provider } from "mobx-react";
import * as React from 'react';
import { RootStore } from '../../../stores/RootStore';
import { MobxTutorial } from './MobxTutorial';
export default class MobxTutorialProvider extends React.Component<{}, {}> {
private readonly dependencies = { rootStore: new RootStore() };
export type MobxTutorialProviderOwnProps = {
stores: {};
};
export default class MobxTutorialProvider extends React.Component<MobxTutorialProviderOwnProps, {}> {
public render(): React.ReactElement<{}> {
return (
<Provider {...this.dependencies.rootStore}>
<Provider {...this.props.stores}>
<MobxTutorial></MobxTutorial>
</Provider>
);

View File

@ -15,7 +15,6 @@ export type ProgressIndicatorProps = Partial<ProgressIndicatorStoreProps> & Prog
export class ProgressIndicator extends React.Component<ProgressIndicatorProps, {}> {
public render(): React.ReactElement<ProgressIndicatorProps> {
const { appStore } = this.props;
return (<>{appStore.appStatus}</>);
}
}

View File

@ -1,7 +1,7 @@
define([], function() {
return {
"PropertyPaneDescription": "Description",
"PropertyPaneDescription": "Application configuration",
"BasicGroupName": "Group Name",
"DescriptionFieldLabel": "Description Field"
"AppTitleFieldLabel": "Application Title Field"
}
});

View File

@ -1,7 +1,7 @@
declare interface IMobxTutorialWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
AppTitleFieldLabel: string;
}
declare module 'MobxTutorialWebPartStrings' {