Skip to content

Commit 31de03a

Browse files
committed
first flow
1 parent 95dde86 commit 31de03a

File tree

12 files changed

+127
-77
lines changed

12 files changed

+127
-77
lines changed

src/client/components/dimension-tile/dimension-tile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export class DimensionTile extends React.Component<DimensionTileProps, Dimension
324324
return {
325325
selected: filterMode === value,
326326
onSelect: this.changeFilterMode.bind(this, value),
327-
displayValue: STRINGS[value],
327+
displayValue: (STRINGS as any)[value],
328328
keyString: value
329329
};
330330
});

src/client/config/constants.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export const SPLIT = 'SPLIT';
3939
export const MAX_SEARCH_LENGTH = 300;
4040
export const SEARCH_WAIT = 900;
4141

42-
export const STRINGS: any = {
42+
// Do not set an explicit type for STRINGS, let typescript figure it out and type check that we are using string correctly
43+
export const STRINGS = {
4344
add: 'Add',
4445
addFromCube: 'Add from Cube',
4546
addNewCollection: 'Add new collection',
@@ -68,7 +69,7 @@ export const STRINGS: any = {
6869
create: 'Create',
6970
cubes: 'cubes',
7071
dataCubes: 'Data Cubes',
71-
delete: 'Delete',
72+
'delete': 'Delete',
7273
deleteCollection: 'Delete this collection',
7374
deleteCollectionTile: 'Delete this tile',
7475
dimensions: 'Dimensions',
@@ -107,10 +108,10 @@ export const STRINGS: any = {
107108
next: 'Next',
108109
no: 'No',
109110
noIllCreateThem: 'No, I\'ll create them myself',
110-
noClusters: 'No clusters',
111+
noClusters: 'There are no clusters configured',
112+
noDataCubes: 'There are no data cubes configured',
111113
noDescription: 'No description',
112114
noFilter: 'No filter',
113-
noQueryableDataCubes: 'There are no queryable data cubes configured',
114115
noTilesInThisCollection: 'There are no tiles in this collection',
115116
ok: 'OK',
116117
openIn: 'Open in',

src/client/modals/cluster-seed-modal/cluster-seed-modal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { indexByAttribute } from '../../../common/utils/array/array';
3030
import { ImmutableFormDelegate, ImmutableFormState } from '../../utils/immutable-form-delegate/immutable-form-delegate';
3131

3232
export interface ClusterSeedModalProps extends React.Props<any> {
33-
onNext: (newCluster: Cluster) => void;
33+
onNext: (newCluster: Cluster, sources: string[]) => void;
3434
onCancel: () => void;
3535
clusters: Cluster[];
3636
}
@@ -76,7 +76,7 @@ export class ClusterSeedModal extends React.Component<ClusterSeedModalProps, Imm
7676
.then(
7777
(resp) => {
7878
var cluster = Cluster.fromJS(resp.cluster);
79-
this.props.onNext(cluster);
79+
this.props.onNext(cluster, resp.sources);
8080
},
8181
(xhr: XMLHttpRequest) => Notifier.failure('Woops', 'Something bad happened')
8282
)

src/client/modals/data-cube-seed-modal/data-cube-seed-modal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ export class DataCubeSeedModal extends React.Component<DataCubeSeedModalProps, D
8383
if (!this.mounted) return;
8484
const { clusters } = this.props;
8585

86-
var clusterSources = resp.clusterSources.map((cs: { cluster: string, source: string }): ClusterSource => {
86+
var clusterSources = resp.clusterSources.map((cs: { clusterName: string, source: string }): ClusterSource => {
8787
return {
88-
cluster: findByName(clusters, cs.cluster),
88+
cluster: findByName(clusters, cs.clusterName),
8989
source: cs.source
9090
};
9191
});

src/client/modals/suggestion-modal/suggestion-modal.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
*/
1616

1717
require('./suggestion-modal.css');
18+
1819
import * as React from 'react';
1920
import { Button, Modal } from '../../components/index';
20-
import { List } from 'immutable';
2121
import { STRINGS } from "../../config/constants";
22-
import { Dimension, Measure, DataCube } from "../../../common/models/index";
2322
import { pluralIfNeeded } from "../../../common/utils/general/general";
2423

2524
import { Checkbox } from "../../components/checkbox/checkbox";
@@ -39,13 +38,14 @@ export interface Suggestion<T> {
3938

4039
export interface SuggestionModalProps<T> extends React.Props<any> {
4140
onAdd: (suggestions: T[]) => void;
41+
onNothing?: () => void;
4242
onClose: () => void;
4343
getLabel: (o: T) => string;
4444
getKey?: (o: T) => string;
4545
options: T[];
4646
title: string;
4747
okLabel?: (c: number) => string;
48-
cancelLabel?: string;
48+
nothingLabel?: string;
4949
}
5050

5151
export interface SuggestionModalState<T> {
@@ -152,8 +152,18 @@ export class SuggestionModal<T> extends React.Component<SuggestionModalProps<T>,
152152
}));
153153
}
154154

155+
renderSecondaryButton() {
156+
const { onClose, onNothing, nothingLabel } = this.props;
157+
158+
if (onNothing && nothingLabel) {
159+
return <Button className="cancel" title={nothingLabel} type="secondary" onClick={onNothing}/>;
160+
} else {
161+
return <Button className="cancel" title={STRINGS.cancel} type="secondary" onClick={onClose}/>;
162+
}
163+
}
164+
155165
renderEmpty() {
156-
const { onClose, title, cancelLabel } = this.props;
166+
const { onClose, title } = this.props;
157167

158168
return <Modal
159169
className="suggestion-modal"
@@ -164,17 +174,17 @@ export class SuggestionModal<T> extends React.Component<SuggestionModalProps<T>,
164174
<div className="message">{STRINGS.thereAreNoSuggestionsAtTheMoment}</div>
165175
</div>
166176
<div className="button-bar">
167-
<Button className="cancel" title={cancelLabel || STRINGS.close} type="primary" onClick={onClose}/>
177+
{this.renderSecondaryButton()}
168178
</div>
169179
</Modal>;
170180
}
171181

172182
render() {
173-
const { onClose, title, okLabel, cancelLabel } = this.props;
183+
const { onClose, title, okLabel } = this.props;
174184
const { suggestions } = this.state;
175185
if (!suggestions || suggestions.length === 0) return this.renderEmpty();
176186

177-
const length = List(suggestions).filter((s) => s.selected).size;
187+
const length = suggestions.filter((s) => s.selected).length;
178188
return <Modal
179189
className="suggestion-modal"
180190
title={`${title}`}
@@ -189,7 +199,7 @@ export class SuggestionModal<T> extends React.Component<SuggestionModalProps<T>,
189199
</div>
190200
<div className="button-bar">
191201
<Button type="primary" title={okLabel ? okLabel(length) : `${STRINGS.add} ${pluralIfNeeded(length, title)}`} disabled={length === 0} onClick={this.onAdd.bind(this)}/>
192-
<Button className="cancel" title={cancelLabel || STRINGS.cancel} type="secondary" onClick={onClose}/>
202+
{this.renderSecondaryButton()}
193203
</div>
194204
</Modal>;
195205
}

src/client/views/no-data-view/no-data-view.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,22 @@ export class NoDataView extends React.Component <NoDataViewProps, NoDataViewStat
7777
</div>;
7878
}
7979

80-
renderTitle(mode: Mode): JSX.Element {
80+
renderTitle(): JSX.Element {
81+
const { mode } = this.state;
82+
8183
return <div className="title">
8284
<div className="icon">
8385
<SvgIcon svg={require('../../icons/data-cubes.svg')}/>
8486
</div>
85-
<div className="label">{mode === NoDataView.NO_CUBE ? STRINGS.noQueryableDataCubes : STRINGS.noConnectedData}</div>
87+
<div className="label">{mode === NoDataView.NO_CUBE ? STRINGS.noDataCubes : STRINGS.noClusters}</div>
8688
</div>;
8789
}
8890

89-
renderLink(mode: Mode): JSX.Element {
91+
renderLink(): JSX.Element {
92+
const { stateful} = this.props;
93+
if (!stateful) return null;
94+
const { mode } = this.state;
95+
9096
const link = mode === NoDataView.NO_CUBE
9197
? <a href="#settings/data-cubes">cubes settings</a>
9298
: <a href="#settings/clusters">clusters settings</a>
@@ -96,8 +102,7 @@ export class NoDataView extends React.Component <NoDataViewProps, NoDataViewStat
96102
}
97103

98104
render() {
99-
const { user, onNavClick, onOpenAbout, customization, stateful } = this.props;
100-
const { mode } = this.state;
105+
const { user, onNavClick, onOpenAbout, customization } = this.props;
101106

102107
return <div className="no-data-view">
103108
<NoDataHeaderBar
@@ -112,8 +117,8 @@ export class NoDataView extends React.Component <NoDataViewProps, NoDataViewStat
112117
{this.renderSettingsIcon()}
113118
</NoDataHeaderBar>
114119
<div className="container">
115-
{ this.renderTitle(mode) }
116-
{ stateful ? this.renderLink(mode) : null }
120+
{ this.renderTitle() }
121+
{ this.renderLink() }
117122
</div>
118123
</div>;
119124
}

src/client/views/settings-view/cluster-edit/cluster-edit.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ require('./cluster-edit.css');
1818

1919
import * as React from 'react';
2020
import { List } from 'immutable';
21-
import { Fn, pluralIfNeeded } from '../../../../common/utils/general/general';
21+
import { Fn, pluralIfNeeded, makeTitle } from '../../../../common/utils/general/general';
2222
import { classNames } from '../../../utils/dom/dom';
2323
import { firstUp, IP_REGEX, NUM_REGEX } from '../../../../common/utils/string/string';
2424
import { STRINGS } from '../../../config/constants';
@@ -37,11 +37,11 @@ import { CLUSTER as LABELS } from '../../../../common/models/labels';
3737

3838
export interface ClusterEditProps extends React.Props<any> {
3939
cluster?: Cluster;
40-
onSave: (newCluster: Cluster) => void;
40+
sources?: string[];
41+
onSave: (newCluster: Cluster, dataCubes: DataCube[]) => void;
4142
isNewCluster?: boolean;
4243
onCancel?: () => void;
4344
getSuggestedCubes?: () => DataCube[];
44-
addCubes?: (cubes: DataCube[]) => void;
4545
}
4646

4747
export interface ClusterEditState extends ImmutableFormState<Cluster> {
@@ -87,14 +87,11 @@ export class ClusterEdit extends React.Component<ClusterEditProps, ClusterEditSt
8787
}
8888

8989
save() {
90-
if (this.props.onSave) this.props.onSave(this.state.newInstance);
90+
if (this.props.onSave) this.props.onSave(this.state.newInstance, null);
9191
}
9292

9393
saveAndAddCubes(dataCubes: DataCube[]) {
94-
const { addCubes } = this.props;
95-
96-
this.save();
97-
if (addCubes) addCubes(dataCubes);
94+
if (this.props.onSave) this.props.onSave(this.state.newInstance, dataCubes);
9895
}
9996

10097
goBack() {
@@ -104,24 +101,39 @@ export class ClusterEdit extends React.Component<ClusterEditProps, ClusterEditSt
104101
}
105102

106103
openCreateCubesModal() {
107-
const { showCreateCubesModal } = this.state;
104+
this.setState({
105+
showCreateCubesModal: true
106+
});
107+
}
108+
109+
closeCreateCubesModal() {
108110
this.setState({
109111
showCreateCubesModal: true
110112
});
111113
}
112114

113115
renderCreateCubesModal(): JSX.Element {
114-
const { getSuggestedCubes, addCubes } = this.props;
116+
const { sources } = this.props;
117+
const { newInstance } = this.state;
118+
119+
var sugestedDataCubes: DataCube[] = [];
120+
if (sources) {
121+
sugestedDataCubes = sources.map((source, i) => {
122+
// ToDo: make the name generation here better;
123+
return DataCube.fromClusterAndSource(`${newInstance.name}_${i}`, makeTitle(source), newInstance, source);
124+
});
125+
}
115126

116127
const CubesSuggestionModal = SuggestionModal.specialize<DataCube>();
117128

118129
return <CubesSuggestionModal
119130
onAdd={this.saveAndAddCubes.bind(this)}
120-
onClose={this.save.bind(this)}
131+
onNothing={this.save.bind(this)}
132+
nothingLabel={STRINGS.noIllCreateThem}
133+
onClose={this.closeCreateCubesModal.bind(this)}
121134
getLabel={(m) => `${m.title}`}
122-
options={getSuggestedCubes()}
135+
options={sugestedDataCubes}
123136
title={STRINGS.createCubesFromCluster}
124-
cancelLabel={STRINGS.noIllCreateThem}
125137
okLabel={(n: number) => `${STRINGS.create} ${pluralIfNeeded(n, 'cube')}`}
126138
/>;
127139
}

src/client/views/settings-view/settings-view.tsx

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface SettingsViewState {
5757
breadCrumbs?: string[];
5858

5959
tempCluster?: Cluster;
60+
tempClusterSources?: string[];
6061
tempDataCube?: DataCube;
6162
}
6263

@@ -121,6 +122,7 @@ export class SettingsView extends React.Component<SettingsViewProps, SettingsVie
121122
window.location.hash = `settings/${value}`;
122123
this.setState({
123124
tempCluster: null,
125+
tempClusterSources: null,
124126
tempDataCube: null
125127
});
126128
}
@@ -147,37 +149,31 @@ export class SettingsView extends React.Component<SettingsViewProps, SettingsVie
147149

148150
// -- Cluster creation flow
149151

150-
createCluster(newCluster: Cluster) {
152+
createCluster(newCluster: Cluster, sources: string[]) {
151153
this.setState({
152-
tempCluster: newCluster
154+
tempCluster: newCluster,
155+
tempClusterSources: sources
153156
});
154157
}
155158

156-
addCluster(newCluster: Cluster) {
157-
this.onSave(
158-
ImmutableUtils.addInArray(this.state.settings, 'clusters', newCluster),
159-
'Cluster created'
160-
).then(this.backToClustersView.bind(this));
161-
}
162-
163-
askForCubes() {
164-
const { settings } = this.state;
165-
return settings.getSuggestedCubes();
166-
}
159+
addClusterAndDataCubes(newCluster: Cluster, newDataCubes: DataCube[]) {
160+
console.log('before:', this.state.settings, newCluster);
161+
var settings = ImmutableUtils.addInArray(this.state.settings, 'clusters', newCluster);
162+
var message = 'Cluster created';
163+
if (newDataCubes && newDataCubes.length) {
164+
settings = settings.appendDataCubes(newDataCubes);
165+
message = 'Cluster and data cubes created';
166+
}
167167

168-
addCubes(newCubes: DataCube[]) {
169-
const { settings } = this.state;
170-
this.onSave(
171-
settings.changeDataCubes(newCubes),
172-
'Cubes added'
173-
).then(this.backToDataCubesView.bind(this));
168+
this.onSave(settings, message).then(this.backToClustersView.bind(this));
174169
}
175170

176171
backToClustersView() {
177172
window.location.hash = '#settings/clusters';
178173

179174
this.setState({
180-
tempCluster: null
175+
tempCluster: null,
176+
tempClusterSources: null
181177
});
182178
}
183179

@@ -228,7 +224,7 @@ export class SettingsView extends React.Component<SettingsViewProps, SettingsVie
228224

229225
render() {
230226
const { user, onNavClick, customization } = this.props;
231-
const { settings, breadCrumbs, tempCluster, tempDataCube } = this.state;
227+
const { settings, breadCrumbs, tempCluster, tempClusterSources, tempDataCube } = this.state;
232228

233229
if (!settings) return null;
234230

@@ -282,9 +278,8 @@ export class SettingsView extends React.Component<SettingsViewProps, SettingsVie
282278
? <ClusterEdit
283279
isNewCluster={true}
284280
cluster={tempCluster}
285-
getSuggestedCubes={this.askForCubes.bind(this)}
286-
addCubes={this.addCubes.bind(this)}
287-
onSave={this.addCluster.bind(this)}
281+
sources={tempClusterSources}
282+
onSave={this.addClusterAndDataCubes.bind(this)}
288283
onCancel={this.backToClustersView.bind(this)}
289284
/>
290285
: <ClusterSeedModal

0 commit comments

Comments
 (0)