瀏覽代碼

Introduce Datasets

crobi 9 年之前
父節點
當前提交
baf468899c

+ 23
- 22
client/css/rpg-cards.css 查看文件

65
     margin: .5rem;
65
     margin: .5rem;
66
     width: 20rem;
66
     width: 20rem;
67
     height: 12rem;
67
     height: 12rem;
68
+    border: 1px solid gray;
68
 
69
 
69
     display: flex;
70
     display: flex;
70
     flex-direction: column;
71
     flex-direction: column;
71
 
72
 
72
-    background-color: rgb(255, 255, 255);
73
-
74
     page-break-inside: avoid;
73
     page-break-inside: avoid;
75
-    border-radius: 4px;
76
-    box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37);
77
-}
78
-.deck-tile-header {
79
-    background-color: #F44336;
80
-    color: rgb(255, 255, 255);
81
-    display: flex;
82
-    flex-direction: row;
83
-    padding: 0.5rem;
84
-    border-radius: 4px 4px 0 0;
85
-    font-size: 1.2rem;
86
-    font-weight: 400;
87
-}
88
-.deck-tile-header:hover {
89
-    background-color: rgb(96, 104, 126);
90
-    cursor: pointer;
91
 }
74
 }
92
-.deck-tile-header-name {
93
-    flex: 1;
75
+.deck-tile :hover {
76
+    background-color: rgb(200, 200, 255);
94
 }
77
 }
95
-.deck-tile-header-id {
78
+.deck-tile-content {
79
+    flex-grow: 1;
80
+    display: flex;
81
+    flex-direction: column;
96
 
82
 
83
+    background-color: white;
84
+
85
+    page-break-inside: avoid;
97
 }
86
 }
87
+.deck-tile-header {
88
+    font-weight: 700;
89
+    padding: 1rem;
90
+    font-size: 1.28571429em;
91
+    line-height: 1.2857em;
92
+    background-color: #3F51B5;
93
+    color: white;
94
+}
95
+.deck-tile-meta {
96
+    font-size: 1em;
97
+    color: rgba(0,0,0,.4);
98
+ }
98
 .deck-tile-body {
99
 .deck-tile-body {
99
     flex: 1;
100
     flex: 1;
101
+    padding: 1rem;
100
     display: flex;
102
     display: flex;
101
     justify-content: center;
103
     justify-content: center;
102
     flex-direction: column;
104
     flex-direction: column;
115
 }
117
 }
116
 .deck-tile-footer {
118
 .deck-tile-footer {
117
     padding: 0.5rem;
119
     padding: 0.5rem;
118
-    border-radius: 0 0 4px 4px;
119
     color: #a8a8a8;
120
     color: #a8a8a8;
120
     background: #eaeaea;
121
     background: #eaeaea;
121
 }
122
 }

+ 89
- 37
client/src/actions/actions.ts 查看文件

10
     export class ActionNewDeck implements Action {
10
     export class ActionNewDeck implements Action {
11
         constructor() {}
11
         constructor() {}
12
     }
12
     }
13
+    export class ActionDeleteDeck implements Action {
14
+        constructor(private _id: EntityId) {}
15
+        get id(): EntityId {return this._id}
16
+    }
13
     export class ActionSetDeckName implements Action {
17
     export class ActionSetDeckName implements Action {
14
-        constructor(private _id: string, private _name:string) {}
15
-        get id(): string {return this._id}
18
+        constructor(private _id: EntityId, private _name:string) {}
19
+        get id(): EntityId {return this._id}
16
         get name(): string {return this._name}
20
         get name(): string {return this._name}
17
     }
21
     }
18
     export class ActionSetDeckDescription implements Action {
22
     export class ActionSetDeckDescription implements Action {
19
-        constructor(private _id: string, private _desc:string) {}
20
-        get id(): string {return this._id}
23
+        constructor(private _id: EntityId, private _desc:string) {}
24
+        get id(): EntityId {return this._id}
21
         get desc(): string {return this._desc}
25
         get desc(): string {return this._desc}
22
     }
26
     }
23
-    export class ActionDeleteDeck implements Action {
24
-        constructor(private _id: string) {}
25
-        get id(): string {return this._id}
27
+    export class ActionDeckAddDataset implements Action {
28
+        constructor(private _deck_id: EntityId, private _dataset_id: EntityId) {}   
29
+        get deck_id(): EntityId {return this._deck_id}
30
+        get dataset_id(): EntityId {return this._dataset_id}
26
     }
31
     }
27
-    export class ActionSelectDeck implements Action {
28
-        constructor(private _id: string) {}
29
-        get id(): string {return this._id}
32
+    export class ActionDeckRemoveDataset implements Action {
33
+        constructor(private _deck_id: EntityId, private _dataset_id: EntityId) {}   
34
+        get deck_id(): EntityId {return this._deck_id}
35
+        get dataset_id(): EntityId {return this._dataset_id} 
36
+    }
37
+    export class ActionSetDeckTemplate implements Action {
38
+        constructor(private _deck_id: EntityId, private _template_id: EntityId) {}
39
+        get deck_id(): EntityId {return this._deck_id}
40
+        get template_id(): EntityId {return this._template_id}
41
+    }
42
+    
43
+    /* Dataset actions */
44
+    export class ActionNewDataset implements Action {
45
+        constructor() {}
46
+    }
47
+    export class ActionDeleteDataset implements Action {
48
+        constructor(private _id: EntityId) {}
49
+        get id(): EntityId {return this._id}
50
+    }
51
+    export class ActionSetDatasetName implements Action {
52
+        constructor(private _id: EntityId, private _name: string) {}
53
+        get id(): EntityId {return this._id}
54
+        get name(): string {return this._name}
30
     }
55
     }
31
 
56
 
32
-    /* Card actions */
33
-    export class ActionNewCard implements Action {
34
-        constructor(private _deck_id: string) {}
35
-        get deck_id(): string {return this._deck_id}
36
-    }
37
-    export class ActionDeleteCard implements Action {
38
-        constructor(private _id: string) {}
39
-        get id(): string {return this._id}
40
-    }
41
-    export class ActionSelectCard implements Action {
42
-        constructor(private _id: string) {}
43
-        get id(): string {return this._id}
44
-    }
45
-    export class ActionModifyCard implements Action {
46
-        constructor(private _id: string, private _prop: string, private _val: string) {}
47
-        get id(): string {return this._id}
57
+    /* Record actions */
58
+    export class ActionNewRecord implements Action {
59
+        constructor(private _dataset_id: EntityId) {}
60
+        get dataset_id(): EntityId {return this._dataset_id}
61
+    }
62
+    export class ActionDeleteRecord implements Action {
63
+        constructor(private _id: EntityId) {}
64
+        get id(): EntityId {return this._id}
65
+    }
66
+    export class ActionModifyRecord implements Action {
67
+        constructor(private _id: EntityId, private _prop: string, private _val: string) {}
68
+        get id(): EntityId {return this._id}
48
         get prop(): string {return this._prop}
69
         get prop(): string {return this._prop}
49
         get val(): string {return this._val}
70
         get val(): string {return this._val}
50
     }
71
     }
72
+    
73
+    /* Template actions */
74
+    export class ActionNewTemplate implements Action {
75
+        constructor() {}
76
+    }
77
+    export class ActionDeleteTemplate implements Action {
78
+        constructor(private _id: EntityId) {}
79
+        get id(): EntityId {return this._id}
80
+    }
51
 
81
 
82
+    /* Helper class for easy dispatching of actions */
52
     export class Actions  {
83
     export class Actions  {
53
         constructor(private _dispatcher: Dispatcher) {
84
         constructor(private _dispatcher: Dispatcher) {
54
         }
85
         }
58
         public newDeck(): void {
89
         public newDeck(): void {
59
             this._dispatcher.dispatch(new ActionNewDeck());
90
             this._dispatcher.dispatch(new ActionNewDeck());
60
         }
91
         }
61
-        public setDeckName(id:string, name:string): void {
92
+        public setDeckName(id:EntityId, name:string): void {
62
             this._dispatcher.dispatch(new ActionSetDeckName(id, name));
93
             this._dispatcher.dispatch(new ActionSetDeckName(id, name));
63
         }
94
         }
64
-        public setDeckDesc(id:string, desc:string): void {
95
+        public setDeckDesc(id:EntityId, desc:string): void {
65
             this._dispatcher.dispatch(new ActionSetDeckDescription(id, desc));
96
             this._dispatcher.dispatch(new ActionSetDeckDescription(id, desc));
66
         }
97
         }
67
-        public deleteDeck(id: string): void {
98
+        public setDeckTemplate(deck_id:EntityId, template_id:EntityId): void {
99
+            this._dispatcher.dispatch(new ActionSetDeckTemplate(deck_id, template_id));
100
+        }
101
+        public addDeckDataset(deck_id:EntityId, dataset_id:EntityId): void {
102
+            this._dispatcher.dispatch(new ActionDeckAddDataset(deck_id, dataset_id));
103
+        }
104
+        public removeDeckDataset(deck_id:EntityId, dataset_id:EntityId): void {
105
+            this._dispatcher.dispatch(new ActionDeckRemoveDataset(deck_id, dataset_id));
106
+        }
107
+        public deleteDeck(id: EntityId): void {
68
             this._dispatcher.dispatch(new ActionDeleteDeck(id));
108
             this._dispatcher.dispatch(new ActionDeleteDeck(id));
69
         }
109
         }
70
-        public selectDeck(id: string): void {
71
-            this._dispatcher.dispatch(new ActionSelectDeck(id));
110
+        public newDataset(): void {
111
+            this._dispatcher.dispatch(new ActionNewDataset());
112
+        }
113
+        public setDatasetName(id:EntityId, name:string): void {
114
+            this._dispatcher.dispatch(new ActionSetDatasetName(id, name));
115
+        }
116
+        public deleteDataset(id: EntityId): void {
117
+            this._dispatcher.dispatch(new ActionDeleteDataset(id));
118
+        }
119
+        public newTemplate(): void {
120
+            this._dispatcher.dispatch(new ActionNewTemplate());
121
+        }
122
+        public deleteTemplate(id: EntityId): void {
123
+            this._dispatcher.dispatch(new ActionDeleteTemplate(id));
72
         }
124
         }
73
-        public newCard(deck_id: string): void {
74
-            this._dispatcher.dispatch(new ActionNewCard(deck_id));
125
+        public newRecord(dataset_id: EntityId): void {
126
+            this._dispatcher.dispatch(new ActionNewRecord(dataset_id));
75
         }
127
         }
76
-        public deleteCard(id: string): void {
77
-            this._dispatcher.dispatch(new ActionDeleteCard(id));
128
+        public deleteRecord(id: EntityId): void {
129
+            this._dispatcher.dispatch(new ActionDeleteRecord(id));
78
         }
130
         }
79
-        public selectCard(id: string): void {
80
-            this._dispatcher.dispatch(new ActionSelectCard(id));
131
+        public modifyRecord(id: EntityId, prop: string, value: any): void {
132
+            this._dispatcher.dispatch(new ActionModifyRecord(id, prop, value));
81
         }
133
         }
82
     }
134
     }
83
 
135
 

+ 59
- 13
client/src/app.ts 查看文件

61
         var withDeckId = (i: number, fn: (deckId: string)=>void) => {
61
         var withDeckId = (i: number, fn: (deckId: string)=>void) => {
62
             appStore.getDeckList().lift(ids => fn(ids[i]));
62
             appStore.getDeckList().lift(ids => fn(ids[i]));
63
         }
63
         }
64
+        var withDatasetId = (i: number, fn: (datasetId: string)=>void) => {
65
+            appStore.getDatasetList().lift(ids => fn(ids[i]));
66
+        }
67
+        var withTemplateId = (i: number, fn: (datasetId: string)=>void) => {
68
+            appStore.getTemplateList().lift(ids => fn(ids[i]));
69
+        }
64
         appActions.reset();
70
         appActions.reset();
71
+        
72
+        // Dataset 1
73
+        appActions.newDataset();
74
+        withDatasetId(0, id=> {
75
+            appActions.setDatasetName(id, "Player's Basic Rules spells");
76
+            appActions.newRecord(id);
77
+            appActions.newRecord(id);
78
+            appActions.newRecord(id);
79
+        });
80
+
81
+        // Dataset 2
82
+        appActions.newDataset();
83
+        withDatasetId(1, id=> {
84
+            appActions.setDatasetName(id, "Elemental Evil spells");
85
+            appActions.newRecord(id);
86
+            appActions.newRecord(id);
87
+            appActions.newRecord(id);
88
+        });
89
+        
90
+        // Dataset 3
91
+        appActions.newDataset();
92
+        withDatasetId(2, id=> {
93
+            appActions.setDatasetName(id, "DM's Basic Rules creatures");
94
+            appActions.newRecord(id);
95
+            appActions.newRecord(id);
96
+            appActions.newRecord(id);
97
+        });
98
+        
99
+        // Template 1
100
+        appActions.newTemplate();
101
+        
102
+        // Template 2
103
+        appActions.newTemplate();
65
 
104
 
66
         // Deck 1
105
         // Deck 1
67
         appActions.newDeck();
106
         appActions.newDeck();
68
-        withDeckId(0, id=>appActions.setDeckName(id, "Spells"));
69
-        withDeckId(0, id=>appActions.setDeckDesc(id, "This deck contains"
70
-            + " basic spells."));
71
-        withDeckId(0, id=>appActions.newCard(id));
72
-        withDeckId(0, id=>appActions.newCard(id));
73
-        withDeckId(0, id=>appActions.newCard(id));
107
+        withDeckId(0, id=>{
108
+            appActions.setDeckName(id, "Wizard spells");
109
+            appActions.setDeckDesc(id, "This deck contains wizard and sorcerer spells.");
110
+            withTemplateId(0, id2=>appActions.setDeckTemplate(id, id2));
111
+            withDatasetId(0, id2=>appActions.addDeckDataset(id, id2));
112
+            withDatasetId(1, id2=>appActions.addDeckDataset(id, id2));
113
+        });
74
 
114
 
75
         // Deck 2
115
         // Deck 2
76
         appActions.newDeck();
116
         appActions.newDeck();
77
-        withDeckId(1, id=>appActions.setDeckName(id, "Items"));
78
-        withDeckId(1, id=>appActions.setDeckDesc(id, "This deck contains"
79
-            + " mundane and magic items."));
80
-        appStore.getDeckList().lift(deckIds => appActions.newCard(deckIds[1]));
117
+        withDeckId(1, id=>{
118
+            appActions.setDeckName(id, "Cleric spells");
119
+            appActions.setDeckDesc(id, "This deck contains cleric spells.");
120
+            withTemplateId(0, id2=>appActions.setDeckTemplate(id, id2));
121
+            withDatasetId(0, id2=>appActions.addDeckDataset(id, id2));
122
+            withDatasetId(1, id2=>appActions.addDeckDataset(id, id2));
123
+        });
81
 
124
 
82
         // Deck 3
125
         // Deck 3
83
         appActions.newDeck();
126
         appActions.newDeck();
84
-        withDeckId(2, id=>appActions.setDeckName(id, "Creatures"));
85
-        withDeckId(2, id=>appActions.setDeckDesc(id, "This deck contains"
86
-            + " creatures."));
127
+        withDeckId(2, id=>{
128
+            appActions.setDeckName(id, "Creatures");
129
+            appActions.setDeckDesc(id, "This deck contains creatures.");
130
+            withTemplateId(1, id2=>appActions.setDeckTemplate(id, id2));
131
+            withDatasetId(2, id2=>appActions.addDeckDataset(id, id2));
132
+        });
87
     }
133
     }
88
 
134
 
89
 }
135
 }

+ 24
- 0
client/src/stores/dataset.ts 查看文件

1
+/// <reference path="./entity.ts"/>
2
+
3
+module rpgcards {
4
+
5
+    export class CardDataSet extends Entity {
6
+        public recordIds: EntityId[];
7
+        public properties: string[];
8
+
9
+        constructor(id:EntityId) {
10
+            super(id);
11
+            this.recordIds = [];
12
+            this.properties = [];
13
+        }
14
+    }
15
+
16
+    export class CardData extends Entity {
17
+        public data: {[name:string]: any};
18
+
19
+        constructor(id:EntityId) {
20
+            super(id);
21
+            this.data = {};
22
+        }
23
+    }
24
+}

+ 5
- 5
client/src/stores/deck.ts 查看文件

2
 
2
 
3
 module rpgcards {
3
 module rpgcards {
4
     export class Deck extends Entity{
4
     export class Deck extends Entity{
5
-        public cards: string[];
5
+        public datasetIds: EntityId[];
6
+        public templateId: EntityId;
6
         public description: string;
7
         public description: string;
7
 
8
 
8
-        constructor(id:string) {
9
+        constructor(id:EntityId) {
9
             super(id);
10
             super(id);
10
-            this.cards = [];
11
+            this.datasetIds = [];
12
+            this.templateId = null;
11
             this.description = "";
13
             this.description = "";
12
         }
14
         }
13
 
15
 
14
     }
16
     }
15
-
16
-    export type DeckList = Deck[];
17
 }
17
 }

+ 5
- 3
client/src/stores/entity.ts 查看文件

1
+/// <reference path="./id.ts"/>
2
+
1
 module rpgcards {
3
 module rpgcards {
2
 
4
 
3
     export class Entity {
5
     export class Entity {
4
-        private _id: string;
6
+        private _id: EntityId;
5
         public name: string;
7
         public name: string;
6
 
8
 
7
-        constructor(id: string) {
9
+        constructor(id: EntityId) {
8
             this._id = id;
10
             this._id = id;
9
             this.name = "";
11
             this.name = "";
10
         }
12
         }
11
 
13
 
12
-        get id(): string {return this._id;}
14
+        get id(): EntityId {return this._id;}
13
     }
15
     }
14
 
16
 
15
 }
17
 }

+ 2
- 0
client/src/stores/id.ts 查看文件

1
 module rpgcards {
1
 module rpgcards {
2
     const s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2
     const s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
3
     const N = 16;
3
     const N = 16;
4
+    
5
+    export type EntityId = string;
4
 
6
 
5
     export function randomID(): string {
7
     export function randomID(): string {
6
         var id = "";
8
         var id = "";

+ 115
- 56
client/src/stores/store.ts 查看文件

18
 
18
 
19
     export class Store extends ChangeEventEmitter {
19
     export class Store extends ChangeEventEmitter {
20
         private _decks: Deck[];
20
         private _decks: Deck[];
21
-        private _cards: Card[];
22
-        private _selectedDeck: string;
23
-        private _selectedCard: string;
21
+        private _datasets: CardDataSet[];
22
+        private _records: CardData[];
23
+        private _templates: CardTemplate[];
24
 
24
 
25
         constructor(dispatcher: Dispatcher) {
25
         constructor(dispatcher: Dispatcher) {
26
             super();
26
             super();
27
             this._decks = [];
27
             this._decks = [];
28
-            this._cards = [];
29
-            this._selectedCard = "";
30
-            this._selectedDeck = "";
28
+            this._datasets = [];
29
+            this._records = [];
30
+            this._templates = [];
31
 
31
 
32
             dispatcher.register((action) => {
32
             dispatcher.register((action) => {
33
+                /* Generic */
33
                 if(action instanceof ActionReset) {
34
                 if(action instanceof ActionReset) {
34
                     this._reset()
35
                     this._reset()
35
-                } else if(action instanceof ActionNewDeck) {
36
+                }
37
+                /* Deck */
38
+                else if(action instanceof ActionNewDeck) {
36
                     this._newDeck()
39
                     this._newDeck()
37
-                } else if (action instanceof ActionDeleteDeck) {
40
+                }
41
+                else if (action instanceof ActionDeleteDeck) {
38
                     this._deleteDeck(action.id);
42
                     this._deleteDeck(action.id);
39
-                } else if (action instanceof ActionSetDeckName) {
43
+                }
44
+                else if (action instanceof ActionSetDeckName) {
40
                     this._modifyDeck(action.id, (deck)=>{
45
                     this._modifyDeck(action.id, (deck)=>{
41
                         deck.name = action.name});
46
                         deck.name = action.name});
42
-                } else if (action instanceof ActionSetDeckDescription) {
43
-                    this._modifyDeck(action.id, (deck)=>{
44
-                        deck.description = action.desc});
45
-                } else if (action instanceof ActionSelectDeck) {
46
-                    this._selectDeck(action.id);
47
-                } else if (action instanceof ActionNewCard) {
48
-                    this._newCard(action.deck_id);
49
-                } else if (action instanceof ActionDeleteCard) {
50
-                    this._deleteCard(action.id);
51
-                } else if (action instanceof ActionSelectCard) {
52
-                    this._selectCard(action.id);
53
-                } else {
54
-                    console.log("Unknown action received");
47
+                }
48
+                else if (action instanceof ActionSetDeckDescription) {
49
+                    this._modifyDeck(action.id, deck=>{
50
+                        deck.description = action.desc;
51
+                    });
52
+                }
53
+                else if (action instanceof ActionSetDeckTemplate) {
54
+                    this._modifyDeck(action.deck_id, deck=>{
55
+                        deck.templateId = action.template_id;
56
+                    });
57
+                }
58
+                else if (action instanceof ActionDeckAddDataset) {
59
+                    this._modifyDeck(action.deck_id, deck=>{
60
+                        deck.datasetIds.push(action.dataset_id);
61
+                    });
62
+                }
63
+                else if (action instanceof ActionDeckRemoveDataset) {
64
+                    this._modifyDeck(action.deck_id, deck=>{
65
+                        deck.datasetIds.filter(id=>id!=action.dataset_id);
66
+                    });
67
+                }
68
+                /* Dataset */
69
+                else if (action instanceof ActionNewDataset) {
70
+                    this._newDataset();                
71
+                }
72
+                else if (action instanceof ActionDeleteDataset) {
73
+                    this._deleteDataset(action.id);                
74
+                }
75
+                else if (action instanceof ActionSetDatasetName) {
76
+                    this._modifyDataset(action.id, dataset=>{
77
+                        dataset.name = action.name;
78
+                    });                
79
+                }
80
+                /* Record */
81
+                else if (action instanceof ActionNewRecord) {
82
+                    this._newRecord(action.dataset_id);
83
+                }
84
+                else if (action instanceof ActionDeleteRecord) {
85
+                    this._deleteRecord(action.id);
86
+                }
87
+                /* Template */
88
+                else if (action instanceof ActionNewTemplate) {
89
+                    this._newTemplate();
90
+                }
91
+                else if (action instanceof ActionDeleteTemplate) {
92
+                    this._deleteTemplate(action.id);
93
+                }
94
+                /* Unknown */
95
+                else {
96
+                    throw new Error("Unknown action received");
55
                 }
97
                 }
56
                 this.emitChange();
98
                 this.emitChange();
57
             });
99
             });
61
         // Accessing data
103
         // Accessing data
62
         // ---------------------------------------------------------------------
104
         // ---------------------------------------------------------------------
63
 
105
 
106
+        getDatasetList(): AsyncT<string[]> {
107
+            return AsyncT.just(
108
+                this._datasets.map(ds => ds.id)
109
+                );
110
+        }
111
+          
112
+        getDataset(id: EntityId): AsyncT<CardDataSet> {
113
+            return findEntity(this._datasets, id);
114
+        }
115
+              
64
         getDeckList(): AsyncT<string[]> {
116
         getDeckList(): AsyncT<string[]> {
65
             return AsyncT.just(
117
             return AsyncT.just(
66
                 this._decks.map(deck => deck.id)
118
                 this._decks.map(deck => deck.id)
67
                 );
119
                 );
68
         }
120
         }
69
 
121
 
70
-        getDeck(id: string): AsyncT<Deck> {
122
+        getDeck(id: EntityId): AsyncT<Deck> {
71
             return findEntity(this._decks, id);
123
             return findEntity(this._decks, id);
72
         }
124
         }
73
 
125
 
74
-        getCard(id: string): AsyncT<Card> {
75
-            return findEntity(this._cards, id);
126
+        getRecord(id: EntityId): AsyncT<CardData> {
127
+            return findEntity(this._records, id);
76
         }
128
         }
77
-
78
-        getCardsForDeck(id: string): AsyncT<string[]> {
79
-            return this.getDeck(id).lift(deck => deck.cards);
129
+        
130
+        getTemplateList(): AsyncT<string[]> {
131
+            return AsyncT.just(
132
+                this._templates.map(ds => ds.id)
133
+                );
80
         }
134
         }
81
-
82
-        getDecksForCard(id: string): AsyncT<string[]> {
83
-            return AsyncT.just(this._decks
84
-                .filter(deck => deck.cards.indexOf(id) !== -1)
85
-                .map(deck => deck.id));
135
+        
136
+        getTemplate(id: EntityId): AsyncT<CardTemplate> {
137
+            return findEntity(this._templates, id);
86
         }
138
         }
87
 
139
 
88
-        // ---------------------------------------------------------------------
89
-        // Pseudo-routes
90
-        // ---------------------------------------------------------------------
91
-        get selectedDeck(): string {return this._selectedDeck}
92
-        get selectedCard(): string {return this._selectedCard}
93
-
94
         // ---------------------------------------------------------------------
140
         // ---------------------------------------------------------------------
95
         // Methods for changing the state
141
         // Methods for changing the state
96
         // ---------------------------------------------------------------------
142
         // ---------------------------------------------------------------------
97
         private _reset(): void {
143
         private _reset(): void {
98
             this._decks = [];
144
             this._decks = [];
99
-            this._cards = [];
100
-            this._selectDeck = null;
101
-            this._selectCard = null;
145
+            this._datasets = [];
146
+            this._records = [];
147
+            this._templates = [];
102
         }
148
         }
149
+        
103
         private _newDeck(): void {
150
         private _newDeck(): void {
104
             this._decks.push(new Deck(randomID()));
151
             this._decks.push(new Deck(randomID()));
105
         }
152
         }
108
             this._decks.filter(deck => deck.id !== id);
155
             this._decks.filter(deck => deck.id !== id);
109
         }
156
         }
110
 
157
 
111
-        private _selectDeck(id: string): void {
112
-            this._selectedDeck = id;
158
+        private _modifyDeck(id: EntityId, fn: (deck: Deck)=>void): void {
159
+            this.getDeck(id).lift(deck => fn(deck));
160
+        }
161
+        
162
+        private _newDataset(): void {
163
+            this._datasets.push(new CardDataSet(randomID()));
113
         }
164
         }
114
 
165
 
115
-        private _modifyDeck(id: string, fn: (deck: Deck)=>void): void {
116
-            this.getDeck(id).lift(deck => fn(deck));
166
+        private _deleteDataset(id: EntityId): void {
167
+            this._datasets.filter(Dataset => Dataset.id !== id);
117
         }
168
         }
118
 
169
 
119
-        private _newCard(deckId: string): void {
120
-            this.getDeck(deckId)
121
-                .lift(deck => {
170
+        private _modifyDataset(id: EntityId, fn: (dataset: CardDataSet)=>void): void {
171
+            this.getDataset(id).lift(Dataset => fn(Dataset));
172
+        }
173
+
174
+        private _newRecord(datasetId: EntityId): void {
175
+            this.getDataset(datasetId)
176
+                .lift(ds => {
122
                     var cardId = randomID();
177
                     var cardId = randomID();
123
-                    this._cards.push(new Card(cardId));
124
-                    deck.cards.push(cardId);
178
+                    this._records.push(new CardData(cardId));
179
+                    ds.recordIds.push(cardId);
125
                 });
180
                 });
126
         }
181
         }
127
 
182
 
128
-        private _selectCard(id: string): void {
129
-            this.selectedCard = id;
183
+        private _deleteRecord(id: EntityId): void {
184
+            this._records.filter(card => card.id !== id);
130
         }
185
         }
131
-
132
-        private _deleteCard(id: string): void {
133
-            this._cards.filter(card => card.id !== id);
186
+        
187
+        private _newTemplate(): void {
188
+            this._templates.push(new CardTemplate(randomID()));
189
+        }
190
+        
191
+        private _deleteTemplate(id: EntityId): void {
192
+            this._templates.filter(t => t.id !== id);
134
         }
193
         }
135
     }
194
     }
136
 }
195
 }

+ 14
- 0
client/src/stores/template.ts 查看文件

2
 
2
 
3
 module rpgcards {
3
 module rpgcards {
4
     
4
     
5
+    export class CardTemplate extends Entity{
6
+        public description: string;
7
+        public width: number;
8
+        public height: number;
9
+        public script: string;
10
+
11
+        constructor(id:EntityId) {
12
+            super(id);
13
+            this.description = "";
14
+            this.width = 0;
15
+            this.height = 0;
16
+        }
17
+
18
+    }
5
 }
19
 }

+ 13
- 20
client/src/views/components/deck.ts 查看文件

5
         id       : string;
5
         id       : string;
6
         name     : string;
6
         name     : string;
7
         desc     : string;
7
         desc     : string;
8
-        cards    : number;
9
     }
8
     }
10
     function DeckTilePropsEqual(a:DeckTileProps, b:DeckTileProps) {
9
     function DeckTilePropsEqual(a:DeckTileProps, b:DeckTileProps) {
11
         return a.id === b.id &&
10
         return a.id === b.id &&
12
             a.name === b.name &&
11
             a.name === b.name &&
13
-            a.desc === b.desc &&
14
-            a.cards === b.cards;
12
+            a.desc === b.desc;
15
     }
13
     }
16
 
14
 
17
     interface DeckTileState {
15
     interface DeckTileState {
18
     }
16
     }
19
 
17
 
20
-    export function tileHeader(props: DeckTileProps) {
18
+    export function tileHeader(props: DeckTileProps): React.ReactElement<any> {
21
         return React.DOM.div
19
         return React.DOM.div
22
             ( { className: 'deck-tile-header', onClick: null }
20
             ( { className: 'deck-tile-header', onClick: null }
23
-            , React.DOM.div({ className: 'deck-tile-header-name' }, props.name)
24
-            , React.DOM.div({ className: 'deck-tile-header-id' }, props.id)
21
+            , props.name
25
             );
22
             );
26
     }
23
     }
27
 
24
 
28
-    export function tileBody(props: DeckTileProps) {
25
+    export function tileBody(props: DeckTileProps): React.ReactElement<any> {
29
         return React.DOM.div
26
         return React.DOM.div
30
             ( { className: 'deck-tile-body', onClick: null }
27
             ( { className: 'deck-tile-body', onClick: null }
31
-            , props.desc
28
+            , React.DOM.p(null, props.desc)
32
             );
29
             );
33
     }
30
     }
34
 
31
 
35
-    export function tileFooter(props: DeckTileProps) {
36
-        let cardsText = props.cards + " cards";
37
-        return React.DOM.div
38
-            ( { className: 'deck-tile-footer', onClick: null }
39
-            , cardsText
40
-            );
32
+    export function tileFooter(props: DeckTileProps): React.ReactElement<any> {
33
+        return null;
41
     }
34
     }
42
 
35
 
43
     export class DeckTileSpec extends React.Component<DeckTileProps, DeckTileState> {
36
     export class DeckTileSpec extends React.Component<DeckTileProps, DeckTileState> {
62
 
55
 
63
         render() {
56
         render() {
64
 
57
 
65
-            return React.DOM.div
66
-                ( { className: 'deck-tile' }
67
-                , tileHeader(this.props)
68
-                , tileBody(this.props)
69
-                , tileFooter(this.props)
70
-                );
58
+            return React.DOM.div( { className: 'deck-tile' }
59
+                , React.DOM.div( { className: 'deck-tile-content' }
60
+                    , tileHeader(this.props)
61
+                    , tileBody(this.props)
62
+                    , tileFooter(this.props)
63
+                ));
71
         }
64
         }
72
     }
65
     }
73
 
66
 

+ 2
- 4
client/src/views/decks.ts 查看文件

51
     export function renderDecks(store: Store): React.ReactElement<any> {
51
     export function renderDecks(store: Store): React.ReactElement<any> {
52
         var decks = store.getDeckList().fmap(deckIds => deckIds.map(id => {
52
         var decks = store.getDeckList().fmap(deckIds => deckIds.map(id => {
53
             let deck = store.getDeck(id);
53
             let deck = store.getDeck(id);
54
-            let cards = store.getCardsForDeck(id);
55
 
54
 
56
-            return AsyncT.liftA2(deck, cards, (deck, cards) => {
55
+            return deck.lift(deck => {
57
                 return <React.ReactElement<any>> DeckTile({
56
                 return <React.ReactElement<any>> DeckTile({
58
                     key : deck.id,
57
                     key : deck.id,
59
                     id  : deck.id,
58
                     id  : deck.id,
60
                     desc: deck.description,
59
                     desc: deck.description,
61
-                    name: deck.name,
62
-                    cards: cards.length });
60
+                    name: deck.name});
63
             }).caseOf({
61
             }).caseOf({
64
                 just: (t) => t,
62
                 just: (t) => t,
65
                 nothing: (e) => errorTile(id, e),
63
                 nothing: (e) => errorTile(id, e),

+ 1
- 0
client/tsconfig.json 查看文件

24
         "./src/external/react/react.d.ts",
24
         "./src/external/react/react.d.ts",
25
         "./src/stores/asyncT.ts",
25
         "./src/stores/asyncT.ts",
26
         "./src/stores/card.ts",
26
         "./src/stores/card.ts",
27
+        "./src/stores/dataset.ts",
27
         "./src/stores/deck.ts",
28
         "./src/stores/deck.ts",
28
         "./src/stores/entity.ts",
29
         "./src/stores/entity.ts",
29
         "./src/stores/eventEmitter.ts",
30
         "./src/stores/eventEmitter.ts",

Loading…
取消
儲存