added components to display data (unfinished)
This commit is contained in:
parent
70df646e63
commit
64aed858ae
|
@ -2,6 +2,7 @@ import { RootStore } from "./RootStore";
|
||||||
import { observable, action, computed } from "mobx";
|
import { observable, action, computed } from "mobx";
|
||||||
|
|
||||||
export enum ApplicationStatus {
|
export enum ApplicationStatus {
|
||||||
|
Loading = "Loading",
|
||||||
CreateList = "Create List",
|
CreateList = "Create List",
|
||||||
CreateItems = "Create Items",
|
CreateItems = "Create Items",
|
||||||
Completed = "Completed"
|
Completed = "Completed"
|
||||||
|
@ -14,7 +15,8 @@ export interface IFakeItem {
|
||||||
|
|
||||||
export class AppStore {
|
export class AppStore {
|
||||||
|
|
||||||
@observable public isLoading: boolean;
|
@observable public isLoadingConfiguration: boolean;
|
||||||
|
@observable public isLoadingOtherStuff: boolean;
|
||||||
@observable public status: ApplicationStatus;
|
@observable public status: ApplicationStatus;
|
||||||
@observable public listTitle: string;
|
@observable public listTitle: string;
|
||||||
@observable public items: IFakeItem[];
|
@observable public items: IFakeItem[];
|
||||||
|
@ -28,7 +30,8 @@ export class AppStore {
|
||||||
this.status = ApplicationStatus.CreateList;
|
this.status = ApplicationStatus.CreateList;
|
||||||
this.listTitle = null;
|
this.listTitle = null;
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this.isLoading = true;
|
this.isLoadingConfiguration = true;
|
||||||
|
this.isLoadingOtherStuff = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
|
@ -36,6 +39,16 @@ export class AppStore {
|
||||||
return `The current status is: ${this.status}`;
|
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
|
@action
|
||||||
public confirmListCreation(listTitle: string) {
|
public confirmListCreation(listTitle: string) {
|
||||||
this.status = ApplicationStatus.CreateItems;
|
this.status = ApplicationStatus.CreateItems;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
import { action, observable } from "mobx";
|
||||||
import { RootStore } from "./RootStore";
|
import { RootStore } from "./RootStore";
|
||||||
import { observable, action, runInAction } from "mobx";
|
|
||||||
|
|
||||||
export class ConfigStore {
|
export class ConfigStore {
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export class ConfigStore {
|
||||||
// Mock REST call for fetching configuration data, 5 seconds
|
// Mock REST call for fetching configuration data, 5 seconds
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loadConfigration();
|
this.loadConfigration();
|
||||||
}, 5000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -26,9 +26,9 @@ export class ConfigStore {
|
||||||
@action
|
@action
|
||||||
private loadConfigration() {
|
private loadConfigration() {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.applicationTitle = "So cool man";
|
this.applicationTitle = "Default Application Title";
|
||||||
this.allowImportantItems = true;
|
this.allowImportantItems = true;
|
||||||
this.rootStore.appStore.isLoading = false;
|
this.rootStore.appStore.isLoadingConfiguration = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { ConfigStore } from "./ConfigStore";
|
|
||||||
import { AppStore } from "./AppStore";
|
import { AppStore } from "./AppStore";
|
||||||
|
import { ConfigStore } from "./ConfigStore";
|
||||||
|
|
||||||
export enum Stores {
|
export enum Stores {
|
||||||
AppStore = "appStore",
|
AppStore = "appStore",
|
||||||
|
@ -9,12 +9,9 @@ export enum Stores {
|
||||||
export class RootStore {
|
export class RootStore {
|
||||||
public readonly appStore: AppStore;
|
public readonly appStore: AppStore;
|
||||||
public readonly configStore: ConfigStore;
|
public readonly configStore: ConfigStore;
|
||||||
public readonly rootStore: RootStore;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.rootStore = this;
|
|
||||||
this.configStore = new ConfigStore(this);
|
this.configStore = new ConfigStore(this);
|
||||||
this.appStore = new AppStore(this);
|
this.appStore = new AppStore(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ import { configure } from "mobx";
|
||||||
import * as strings from 'MobxTutorialWebPartStrings';
|
import * as strings from 'MobxTutorialWebPartStrings';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as ReactDom from 'react-dom';
|
import * as ReactDom from 'react-dom';
|
||||||
import { IMobxTutorialProps } from './components/IMobxTutorialProps';
|
import { RootStore } from '../../stores/RootStore';
|
||||||
import MobxTutorialProvider from './components/MobxTutorialProvider';
|
import MobxTutorialProvider from './components/MobxTutorialProvider';
|
||||||
|
|
||||||
configure({ enforceActions: "always" });
|
configure({ enforceActions: "always" });
|
||||||
|
@ -15,16 +15,27 @@ export interface IMobxTutorialWebPartProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTutorialWebPartProps> {
|
export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTutorialWebPartProps> {
|
||||||
|
private readonly dependencies = { rootStore: new RootStore() };
|
||||||
|
|
||||||
public render(): void {
|
public render(): void {
|
||||||
|
|
||||||
const element: React.ReactElement<{}> = React.createElement(
|
const element: React.ReactElement<{}> = React.createElement(
|
||||||
MobxTutorialProvider,
|
MobxTutorialProvider,
|
||||||
{
|
{
|
||||||
|
stores: { ...this.dependencies.rootStore }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
ReactDom.render(element, this.domElement);
|
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 {
|
protected onDispose(): void {
|
||||||
ReactDom.unmountComponentAtNode(this.domElement);
|
ReactDom.unmountComponentAtNode(this.domElement);
|
||||||
}
|
}
|
||||||
|
@ -44,8 +55,8 @@ export default class MobxTutorialWebPart extends BaseClientSideWebPart<IMobxTuto
|
||||||
{
|
{
|
||||||
groupName: strings.BasicGroupName,
|
groupName: strings.BasicGroupName,
|
||||||
groupFields: [
|
groupFields: [
|
||||||
PropertyPaneTextField('description', {
|
PropertyPaneTextField('Application title', {
|
||||||
label: strings.DescriptionFieldLabel
|
label: strings.AppTitleFieldLabel
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,33 @@
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { AppStore } from '../../../stores/AppStore';
|
import { AppStore } from '../../../stores/AppStore';
|
||||||
|
import { ConfigStore } from '../../../stores/ConfigStore';
|
||||||
import { Stores } from '../../../stores/RootStore';
|
import { Stores } from '../../../stores/RootStore';
|
||||||
|
import { FakeItemContainer } from './FakeItemContainer';
|
||||||
import { ProgressIndicator } from './ProgressIndicator';
|
import { ProgressIndicator } from './ProgressIndicator';
|
||||||
|
|
||||||
export type MobxTutorialStoreProps = {
|
export type MobxTutorialStoreProps = {
|
||||||
appStore: AppStore;
|
appStore: AppStore;
|
||||||
|
configStore: ConfigStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MobxTutorialProps = Partial<MobxTutorialStoreProps>;
|
export type MobxTutorialProps = Partial<MobxTutorialStoreProps>;
|
||||||
|
|
||||||
@inject(Stores.AppStore)
|
@inject(Stores.AppStore, Stores.ConfigurationStore)
|
||||||
@observer
|
@observer
|
||||||
export class MobxTutorial extends React.Component<MobxTutorialProps, {}> {
|
export class MobxTutorial extends React.Component<MobxTutorialProps, {}> {
|
||||||
public render(): React.ReactElement<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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{appStore.isLoading ? "LOADING" : null}
|
<h1>{configStore.applicationTitle}</h1>
|
||||||
<ProgressIndicator></ProgressIndicator>
|
<ProgressIndicator></ProgressIndicator>
|
||||||
|
<FakeItemContainer></FakeItemContainer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { Provider } from "mobx-react";
|
import { Provider } from "mobx-react";
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { RootStore } from '../../../stores/RootStore';
|
|
||||||
import { MobxTutorial } from './MobxTutorial';
|
import { MobxTutorial } from './MobxTutorial';
|
||||||
|
|
||||||
export default class MobxTutorialProvider extends React.Component<{}, {}> {
|
export type MobxTutorialProviderOwnProps = {
|
||||||
private readonly dependencies = { rootStore: new RootStore() };
|
stores: {};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class MobxTutorialProvider extends React.Component<MobxTutorialProviderOwnProps, {}> {
|
||||||
|
|
||||||
public render(): React.ReactElement<{}> {
|
public render(): React.ReactElement<{}> {
|
||||||
return (
|
return (
|
||||||
<Provider {...this.dependencies.rootStore}>
|
<Provider {...this.props.stores}>
|
||||||
<MobxTutorial></MobxTutorial>
|
<MobxTutorial></MobxTutorial>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,7 +15,6 @@ export type ProgressIndicatorProps = Partial<ProgressIndicatorStoreProps> & Prog
|
||||||
export class ProgressIndicator extends React.Component<ProgressIndicatorProps, {}> {
|
export class ProgressIndicator extends React.Component<ProgressIndicatorProps, {}> {
|
||||||
public render(): React.ReactElement<ProgressIndicatorProps> {
|
public render(): React.ReactElement<ProgressIndicatorProps> {
|
||||||
const { appStore } = this.props;
|
const { appStore } = this.props;
|
||||||
|
|
||||||
return (<>{appStore.appStatus}</>);
|
return (<>{appStore.appStatus}</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
define([], function() {
|
define([], function() {
|
||||||
return {
|
return {
|
||||||
"PropertyPaneDescription": "Description",
|
"PropertyPaneDescription": "Application configuration",
|
||||||
"BasicGroupName": "Group Name",
|
"BasicGroupName": "Group Name",
|
||||||
"DescriptionFieldLabel": "Description Field"
|
"AppTitleFieldLabel": "Application Title Field"
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,7 +1,7 @@
|
||||||
declare interface IMobxTutorialWebPartStrings {
|
declare interface IMobxTutorialWebPartStrings {
|
||||||
PropertyPaneDescription: string;
|
PropertyPaneDescription: string;
|
||||||
BasicGroupName: string;
|
BasicGroupName: string;
|
||||||
DescriptionFieldLabel: string;
|
AppTitleFieldLabel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'MobxTutorialWebPartStrings' {
|
declare module 'MobxTutorialWebPartStrings' {
|
||||||
|
|
Loading…
Reference in New Issue