View | Details | Raw Unified | Return to bug 40116
Collapse All | Expand All

(-)umc/js/appcenter.styl (-15 / +25 lines)
 Lines 78-84    Link Here 
78
78
79
.umcAppDetailsPage
79
.umcAppDetailsPage
80
	.umcAppButton
80
	.umcAppButton
81
		float: left
81
		float: right
82
82
83
	.umcAppButton.umcAppButtonFirstRow
83
	.umcAppButton.umcAppButtonFirstRow
84
		margin-bottom: 15px
84
		margin-bottom: 15px
 Lines 86-99    Link Here 
86
	.umcAppButton.umcAppButtonFirstRow + .umcAppButton:not(.umcAppButtonFirstRow)
86
	.umcAppButton.umcAppButtonFirstRow + .umcAppButton:not(.umcAppButtonFirstRow)
87
		clear: left
87
		clear: left
88
88
89
.categoryButton
89
	.umcAppButton.umcActionButton
90
		float: none
91
92
.categoryButton, .categorySpan
90
	background-color: transparent
93
	background-color: transparent
91
	border: 0
94
	border: 0
92
	border-right: 1px solid lightgrey
95
	border-right: 1px solid lightgrey
93
	padding: 0 0.4em 0 0
96
	padding: 0 0.4em 0 0
94
	margin-right: 0.4em
97
	margin-right: 0.4em
95
	text-decoration: underline
96
	opacity: 0.66
97
98
98
	&:first-child
99
	&:first-child
99
		padding-left: 0
100
		padding-left: 0
 Lines 101-106    Link Here 
101
	&:last-child
102
	&:last-child
102
		border-right: 0
103
		border-right: 0
103
104
105
.categoryButton
106
	text-decoration: underline
107
	opacity: 0.66
108
104
	&:hover
109
	&:hover
105
		opacity: 1
110
		opacity: 1
106
111
 Lines 238-247    Link Here 
238
	.dijitButton
243
	.dijitButton
239
		float: right
244
		float: right
240
245
241
.appDetailsPageGrid
246
.appDetailsPageActions
242
	margin-bottom: 3em
247
	margin-bottom: 3em
243
248
244
	.appDetailsPageGridContent
249
	.appDetailsPageActionsContent
245
		height: 105px !important
250
		height: 105px !important
246
251
247
.umc .umcAppDialog
252
.umc .umcAppDialog
 Lines 293-315    Link Here 
293
		.icon
298
		.icon
294
			margin-bottom: 1em
299
			margin-bottom: 1em
295
			width: 100%
300
			width: 100%
301
			max-width: 550px
296
			height: 120px
302
			height: 120px
297
			display: inline-block
303
			display: inline-block
298
			background-position: center center
304
			background-position: left center
299
			background-size: contain
305
			background-size: contain
300
			/* border instead of padding works with background-size:contain */
306
			/* border instead of padding works with background-size:contain */
301
			border-right: solid transparent 20px
307
			border-right: solid transparent 20px
302
308
303
		.navHeaderButton
309
		.navContainer
304
			display: inline-block
310
			display: inline-block
305
			vertical-align: top
311
			width: 100%
306
			padding-left: 0.5em
312
			border-top: 1px solid #c8c8c8
313
			padding: 0.8em 0
307
314
308
			.umcText
315
			.umcText
309
				margin-bottom: 0.3em
316
				margin-bottom: 0.3em
310
				color: #787878
317
				color: #787878
318
			.umcAppStatusText, .umcContainerWidget
319
				display: block
320
				width: 100%
321
				@media screen and (min-width: 550px)
322
					display: inline-block
323
					width: 50%
311
			.umcAppStatusText
324
			.umcAppStatusText
312
				display: inline-block
325
				vertical-align: top
326
313
			.umcEndOfLifeHelp
327
			.umcEndOfLifeHelp
314
				display: inline-block
328
				display: inline-block
315
				position: relative
329
				position: relative
 Lines 363-372    Link Here 
363
		margin-bottom: 3em
377
		margin-bottom: 3em
364
378
365
379
366
	@media (min-width: 550px)
367
		.umcPageNav .icon
368
			width: 50%
369
370
	/* NOTE: _All_ CSS classes textLongerThanXXXChars from _getCSSClass4TextLength() need to be addressed here! */
380
	/* NOTE: _All_ CSS classes textLongerThanXXXChars from _getCSSClass4TextLength() need to be addressed here! */
371
	.descriptionContainer div,
381
	.descriptionContainer div,
372
	.usage
382
	.usage
(-)umc/js/appcenter.js (+8 lines)
 Lines 113-118    Link Here 
113
					this.showApp({id: state[1]});
113
					this.showApp({id: state[1]});
114
				} else {
114
				} else {
115
					if (this._appCenterPage && state[0] === 'category') {
115
					if (this._appCenterPage && state[0] === 'category') {
116
						this.set('title', 'App Center');
116
						this.selectChild(this._appCenterPage);
117
						this.selectChild(this._appCenterPage);
117
						when(this._appCenterPage._searchSidebar.selectFormDeferred, lang.hitch(this, function() {
118
						when(this._appCenterPage._searchSidebar.selectFormDeferred, lang.hitch(this, function() {
118
							this._appCenterPage._searchSidebar.set('category', state[1]);
119
							this._appCenterPage._searchSidebar.set('category', state[1]);
 Lines 216-222    Link Here 
216
			this._appDetailsPage.own(appChooseHostDialog);
217
			this._appDetailsPage.own(appChooseHostDialog);
217
			this._appDetailsPage.own(appDetailsDialog);
218
			this._appDetailsPage.own(appDetailsDialog);
218
			this._appDetailsPage.own(appConfigDialog);
219
			this._appDetailsPage.own(appConfigDialog);
220
			this._appDetailsPage.watch('moduleTitle', lang.hitch(this, function(attr, oldVal, newVal){
221
				if (newVal) {
222
					this.set('title', newVal);
223
				}
224
			}));
225
			this.set('title', app.name);
219
			this._appDetailsPage.on('back', lang.hitch(this, function(category) {
226
			this._appDetailsPage.on('back', lang.hitch(this, function(category) {
227
				this.set('title', 'App Center');
220
				if (category && category.length) {
228
				if (category && category.length) {
221
					this._appCenterPage._searchSidebar.set('category', category);
229
					this._appCenterPage._searchSidebar.set('category', category);
222
				}
230
				}
(-)umc/js/appcenter/AppDetailsPage.js (-132 / +195 lines)
 Lines 56-68    Link Here 
56
	"umc/widgets/ProgressBar",
56
	"umc/widgets/ProgressBar",
57
	"umc/widgets/Page",
57
	"umc/widgets/Page",
58
	"umc/widgets/Text",
58
	"umc/widgets/Text",
59
	"umc/widgets/Button",
59
	"umc/widgets/CheckBox",
60
	"umc/widgets/CheckBox",
60
	"umc/widgets/Grid",
61
	"umc/widgets/Grid",
61
	"umc/modules/appcenter/AppCenterGallery",
62
	"umc/modules/appcenter/AppCenterGallery",
62
	"umc/modules/appcenter/App",
63
	"umc/modules/appcenter/App",
63
	"umc/modules/appcenter/Carousel",
64
	"umc/modules/appcenter/Carousel",
64
	"umc/i18n!umc/modules/appcenter"
65
	"umc/i18n!umc/modules/appcenter"
65
], function(declare, lang, kernel, array, dojoEvent, all, when, query, ioQuery, topic, Deferred, domConstruct, domClass, on, domStyle, Memory, Observable, Tooltip, Lightbox, UMCApplication, tools, dialog, TitlePane, ContainerWidget, ProgressBar, Page, Text, CheckBox, Grid, AppCenterGallery, App, Carousel, _) {
66
], function(declare, lang, kernel, array, dojoEvent, all, when, query, ioQuery, topic, Deferred, domConstruct, domClass, on, domStyle, Memory, Observable, Tooltip, Lightbox, UMCApplication, tools, dialog, TitlePane, ContainerWidget, ProgressBar, Page, Text, Button, CheckBox, Grid, AppCenterGallery, App, Carousel, _) {
66
67
67
	var adaptedGrid = declare([Grid], {
68
	var adaptedGrid = declare([Grid], {
68
		_updateContextActions: function() {
69
		_updateContextActions: function() {
 Lines 78-83    Link Here 
78
		standby: null,
79
		standby: null,
79
80
80
		title: _("App management"),
81
		title: _("App management"),
82
		moduleTitle: null,
81
		noFooter: true,
83
		noFooter: true,
82
		getAppCommand: 'appcenter/get',
84
		getAppCommand: 'appcenter/get',
83
85
 Lines 145-157    Link Here 
145
				this.hostDialog.set('app', app);
147
				this.hostDialog.set('app', app);
146
				this.detailsDialog.set('app', app);
148
				this.detailsDialog.set('app', app);
147
				this.configDialog.set('app', app);
149
				this.configDialog.set('app', app);
148
				this.set('headerText', app.name);
150
				this.renderPage();
149
				//this.set('helpText', app.longDescription);
151
				this.set('moduleTitle', app.name);
150
				this.buildInnerPage();
151
				this.appLoadingDeferred.resolve();
152
				this.appLoadingDeferred.resolve();
152
			}));
153
			}));
153
		},
154
		},
154
155
156
		_setModuleTitleAttr: function(name) {
157
			this._set('moduleTitle', name);
158
			this.moduleTitle = name;
159
		},
160
155
		_appIsInstalledInDomain: function() {
161
		_appIsInstalledInDomain: function() {
156
			return this._appCountInstallations() > 0;
162
			return this._appCountInstallations() > 0;
157
		},
163
		},
 Lines 172-194    Link Here 
172
178
173
		getButtons: function() {
179
		getButtons: function() {
174
			var buttons = [];
180
			var buttons = [];
175
			if (this.app.canOpen() && this.app.isInstalled) {
181
			if (this.app.canOpenInDomain() && this.app.isInstalled) {
176
				buttons.push({
182
				buttons.push({
177
					name: 'open',
183
					name: 'open',
178
					label: this.app.getOpenLabel(),
184
					label: this.app.getOpenLabel(),
179
					defaultButton: true,
185
					defaultButton: true,
180
					'class': 'umcAppButton umcAppButtonFirstRow',
186
					'class': 'umcAppButton',
181
					callback: lang.hitch(this, function() {
187
					callback: lang.hitch(this.app, 'open')
182
						this.app.open();
183
					})
184
				});
188
				});
185
			} else if (this.app.canInstall) {
189
			} else if (this.app.canInstall && !this.app.isInstalled) {
186
				buttons.push({
190
				buttons.push({
187
					name: 'install',
191
					name: 'install',
188
					label: _('Install'),
192
					label: _('Install'),
189
					'class': 'umcAppButton',
193
					'class': 'umcAppButton',
190
					isStandardAction: true,
191
					isContextAction: false,
192
					iconClass: 'umcIconAdd',
194
					iconClass: 'umcIconAdd',
193
					callback: lang.hitch(this.app, 'install')
195
					callback: lang.hitch(this.app, 'install')
194
				});
196
				});
 Lines 199-225    Link Here 
199
					name: 'shop',
201
					name: 'shop',
200
					label: _('Buy'),
202
					label: _('Buy'),
201
					iconClass: 'umcShopIcon',
203
					iconClass: 'umcShopIcon',
202
					'class': 'umcAppButton umcAppButtonFirstRow',
204
					'class': 'umcAppButton',
203
					callback: lang.hitch(this, 'openShop')
205
					callback: lang.hitch(this, 'openShop')
204
				});
206
				});
205
			}
207
			}
206
			return buttons;
208
			return buttons;
207
		},
209
		},
208
210
209
		getActionButtons: function() {
211
		getActionButtons: function(isSingleServerInstallation) {
210
			var buttons = [];
212
			var buttons = [];
211
			if (this.app.canInstall) {
213
			if (this.app.canInstall && this.app.getHosts().length > 1) {
212
				buttons.push({
214
				buttons.push({
213
					name: 'install',
215
					name: 'install',
214
					label: _('Install'),
216
					label: _('Install'),
215
					'class': 'umcAppButton',
217
					'class': 'umcAppButton umcActionButton',
216
					isStandardAction: true,
218
					isStandardAction: true,
217
					isContextAction: false,
219
					isContextAction: false,
218
					iconClass: 'umcIconAdd',
220
					iconClass: 'umcIconAdd',
219
					callback: lang.hitch(this.app, 'install')
221
					callback: lang.hitch(this.app, 'install')
220
				});
222
				});
221
			}
223
			}
222
			if (this.app.canOpenInDomain()) {
224
			if (this.app.canOpenInDomain() && !this.app.isInstalled) {
223
				buttons.push({
225
				buttons.push({
224
					name: 'open',
226
					name: 'open',
225
					label: this.app.getOpenLabel(),
227
					label: this.app.getOpenLabel(),
 Lines 238-244    Link Here 
238
				buttons.push({
240
				buttons.push({
239
					name: 'disable',
241
					name: 'disable',
240
					label: _('Continue using'),
242
					label: _('Continue using'),
241
					'class': 'umcAppButton umcAppButtonFirstRow',
243
					'class': 'umcAppButton umcActionButton',
242
					isContextAction: true,
244
					isContextAction: true,
243
					isStandardAction: true,
245
					isStandardAction: true,
244
					canExecute: lang.hitch(this, function(app) {
246
					canExecute: lang.hitch(this, function(app) {
 Lines 251-257    Link Here 
251
				buttons.push({
253
				buttons.push({
252
					name: 'configure',
254
					name: 'configure',
253
					label: _('App settings'),
255
					label: _('App settings'),
254
					'class': 'umcAppButton',
256
					'class': 'umcAppButton umcActionButton',
255
					isContextAction: true,
257
					isContextAction: true,
256
					isStandardAction: true,
258
					isStandardAction: true,
257
					canExecute: lang.hitch(this, function(app) {
259
					canExecute: lang.hitch(this, function(app) {
 Lines 261-281    Link Here 
261
				});
263
				});
262
			}
264
			}
263
			if (this.app.canUninstallInDomain()) {
265
			if (this.app.canUninstallInDomain()) {
266
				var callback;
267
				if (isSingleServerInstallation) {
268
					callback = lang.hitch(this.app, 'uninstall');
269
				} else {
270
					callback = lang.hitch(this, function(host, app) {
271
						app[0].data.uninstall();
272
					});
273
				}
264
				buttons.push({
274
				buttons.push({
265
					name: 'uninstall',
275
					name: 'uninstall',
266
					label: _('Uninstall'),
276
					label: _('Uninstall'),
267
					isContextAction: true,
277
					isContextAction: true,
268
					isStandardAction: true,
278
					isStandardAction: true,
269
					'class': 'umcAppButton',
279
					'class': 'umcAppButton umcActionButton',
270
					canExecute: lang.hitch(this, function(app) {
280
					canExecute: lang.hitch(this, function(app) {
271
						return app.data.canUninstall();
281
						return app.data.canUninstall();
272
					}),
282
					}),
273
					callback: lang.hitch(this, function(host, app) {
283
					callback: callback
274
						app[0].data.uninstall();
275
					})
276
				});
284
				});
277
			}
285
			}
278
			if (this.app.canUpgradeInDomain()) {
286
			if (this.app.canUpgradeInDomain()) {
287
				var callback;
288
				if (isSingleServerInstallation) {
289
					callback = lang.hitch(this.app, 'upgrade');
290
				} else {
291
					callback = lang.hitch(this, function(host, app) {
292
						app[0].data.upgrade();
293
					});
294
				}
279
				buttons.push({
295
				buttons.push({
280
					name: 'update',
296
					name: 'update',
281
					label: _('Upgrade'),
297
					label: _('Upgrade'),
 Lines 284-308    Link Here 
284
					canExecute: lang.hitch(this, function(app) {
300
					canExecute: lang.hitch(this, function(app) {
285
						return app.data.canUpgrade();
301
						return app.data.canUpgrade();
286
					}),
302
					}),
287
					callback: lang.hitch(this, function(host, app) {
303
					callback: callback
288
						app[0].data.upgrade();
289
					})
290
				});
304
				});
291
			}
305
			}
292
			return buttons;
306
			return buttons;
293
		},
307
		},
294
308
295
		buildInnerPage: function() {
309
		renderPage: function() {
296
			var _getCSSClass4TextLength = function(text) {
310
			this._renderIcon();
297
				var cssClass = '';
311
			this._renderNavContainer();
298
				array.forEach([400, 500, 600, 800], function(ilength) {
312
			this._renderMainContainer();
299
					if (text.length > ilength) {
313
			this._renderFooter();
300
						cssClass = 'textLongerThan' + ilength + 'Chars';
314
		},
301
					}
302
				});
303
				return cssClass;
304
			};
305
315
316
		_renderIcon: function() {
306
			if (this._icon) {
317
			if (this._icon) {
307
				this.removeChild(this._icon);
318
				this.removeChild(this._icon);
308
				this._icon.destroyRecursive();
319
				this._icon.destroyRecursive();
 Lines 317-358    Link Here 
317
				});
328
				});
318
				this.addChild(this._icon, 0);
329
				this.addChild(this._icon, 0);
319
			}
330
			}
331
		},
320
332
321
			if (this._navHeaderButtonContainer) {
333
		_renderNavContainer: function() {
322
				this.removeChild(this._navHeaderButtonContainer);
334
			if (this._navContainer) {
323
				//TODO fix
335
				this.removeChild(this._navContainer);
324
				//this._navHeaderButtonContainer.destroyRecursive();
336
				this._navContainer = null;
325
				this._navHeaderButtonContainer = null;
326
			}
337
			}
327
			this._navHeaderButtonContainer = new ContainerWidget({
338
			this._navContainer = new ContainerWidget({
328
				region: 'nav',
339
				region: 'nav',
329
				'class': 'navHeaderButton'
340
				'class': 'navContainer'
330
			});
341
			});
331
342
332
			this._navHeaderButtonContainer.addChild(this._headerTextPane, 0);
343
			// build Text Widget for HeaderDetails
344
			var _navHeaderDetails = new Text({
345
				'class': 'umcAppStatusText'
346
			});
333
347
348
			// vendor
334
			var vendor = this._detailFieldCustomVendor();
349
			var vendor = this._detailFieldCustomVendor();
335
			if (vendor) {
350
			if (vendor) {
336
				var _vendorTextPane = new Text({
351
				_navHeaderDetails.set('content', vendor);
337
					content: vendor
338
				});
339
				this._navHeaderButtonContainer.addChild(_vendorTextPane);
340
			}
352
			}
341
353
342
			//Status of the App
354
			//Status of the App
343
			if (this.app.isInstalled || this.app.getHosts().length) {
355
			if (this.app.isInstalled || this.app.getHosts().length) {
344
				var informationText = new Text({
345
					'class': 'umcAppStatus'
346
				});
347
				var text = _('Installed');
356
				var text = _('Installed');
348
				if (this.app.endOfLife) {
357
				if (this.app.endOfLife) {
349
					text = _('End of life');
358
					text = _('End of life');
350
					var tooltipText = this._detailFieldCustomEndOfLife();
359
					var tooltipText = this._detailFieldCustomEndOfLife();
351
352
					domConstruct.create('div', {
360
					domConstruct.create('div', {
353
							'class': 'umcEndOfLifeHelp umcHelpIconSmall',
361
							'class': 'umcEndOfLifeHelp umcHelpIconSmall',
354
							onclick: function(evt) {
362
							onclick: function(evt) {
355
								// stolen from system-setup
356
								var node = evt.target;
363
								var node = evt.target;
357
								Tooltip.show(tooltipText, node);
364
								Tooltip.show(tooltipText, node);
358
								if (evt) {
365
								if (evt) {
 Lines 363-369    Link Here 
363
									dojoEvent.stop(evt);
370
									dojoEvent.stop(evt);
364
								});
371
								});
365
							}
372
							}
366
						}, informationText.domNode
373
						}, _navHeaderDetails.domNode
367
					);
374
					);
368
				} else if (this.app.canUpgradeInDomain()) {
375
				} else if (this.app.canUpgradeInDomain()) {
369
					text = _('Update available');
376
					text = _('Update available');
 Lines 371-393    Link Here 
371
				domConstruct.create('div', {
378
				domConstruct.create('div', {
372
					textContent: text,
379
					textContent: text,
373
					'class': 'umcAppStatusText'
380
					'class': 'umcAppStatusText'
374
				}, informationText.domNode, 'first');
381
				}, _navHeaderDetails.domNode);
375
				this._navHeaderButtonContainer.addChild(informationText);
376
			} else {
382
			} else {
377
			//Categories of the App
383
			//Categories of the App
378
				var categoryButtons = this._detailFieldCustomCategories();
384
				var categoryButtons = this._detailFieldCustomCategories();
379
				if (categoryButtons) {
385
				if (categoryButtons) {
380
					this._navHeaderButtonContainer.domNode.appendChild(categoryButtons);
386
					_navHeaderDetails.domNode.appendChild(categoryButtons);
381
				}
387
				}
382
			}
388
			}
383
389
390
			this._navContainer.addChild(_navHeaderDetails);
384
			this.set('navButtons', this.getButtons());
391
			this.set('navButtons', this.getButtons());
385
			this._navButtons.set('style', {'margin-left': '-0.2em', 'margin-top': '1em'});
392
			this._navContainer.addChild(this._navButtons);
386
			this._navHeaderButtonContainer.addChild(this._navButtons);
387
393
388
			this.addChild(this._navHeaderButtonContainer);
394
			this.addChild(this._navContainer);
389
			this.own(this._navHeaderButtonContainer);
395
			this.own(this._navContainer);
396
		},
390
397
398
		_renderMainContainer: function() {
391
			if (this._mainRegionContainer) {
399
			if (this._mainRegionContainer) {
392
				this.removeChild(this._mainRegionContainer);
400
				this.removeChild(this._mainRegionContainer);
393
				this._mainRegionContainer.destroyRecursive();
401
				this._mainRegionContainer.destroyRecursive();
 Lines 397-463    Link Here 
397
			this.addChild(this._mainRegionContainer);
405
			this.addChild(this._mainRegionContainer);
398
			this.own(this._mainRegionContainer);
406
			this.own(this._mainRegionContainer);
399
407
400
			if (this.app.isInstalled || this.app.getHosts().length > 0) {
408
			var isAppInstalled = this.app.isInstalled || this.app.getHosts().length > 0;
401
				var usage = this.app.readme;
409
			if (isAppInstalled) {
402
				if (usage) {
410
				this._renderUsage();
403
					usage = lang.replace(usage, this.app);
411
				this._renderInstallationManagement();
404
				} else {
412
			}
405
					usage = this._detailFieldCustomUsage();
413
			this._renderDetailsPane(isAppInstalled);
406
				}
407
				if (usage) {
408
					usageHeader = new Text({
409
						content: _('First steps'),
410
						'class': 'mainHeader'
411
					});
412
					this._mainRegionContainer.addChild(usageHeader);
413
414
414
					var usageClass = 'usage ' + _getCSSClass4TextLength(usage);
415
			domStyle.set(this._main.domNode, 'margin-bottom', '2em');
415
					var usagePane = new Text({
416
		},
416
						content: usage,
417
						'class': usageClass
418
					});
419
					this._mainRegionContainer.addChild(usagePane);
420
				}
421
417
422
				var gridHeader = new Text({
418
		_renderUsage: function() {
423
					content: _('Manage domain wide installations'),
419
			var usage = this.app.readme;
420
			if (usage) {
421
				usage = lang.replace(usage, this.app);
422
			} else {
423
				usage = this._detailFieldCustomUsage();
424
			}
425
			if (usage) {
426
				usageHeader = new Text({
427
					content: _('First steps'),
424
					'class': 'mainHeader'
428
					'class': 'mainHeader'
425
				});
429
				});
426
				this._mainRegionContainer.addChild(gridHeader);
430
				this._mainRegionContainer.addChild(usageHeader);
427
431
428
				var actions = this.getActionButtons();
432
				var usageClass = 'usage ' + this._getCSSClass4TextLength(usage);
429
433
				var usagePane = new Text({
430
				var columns = [{
434
					content: usage,
431
					name: 'server',
435
					'class': usageClass
432
					label: _('Server')
433
				}, {
434
					name: 'appStatus',
435
					label: _('Status')
436
				}];
437
438
				var myStore = new Observable(new Memory({
439
					data: this.app.getHosts()
440
				}));
441
				this._installedAppsGrid = new adaptedGrid({
442
					'class': 'appDetailsPageGrid',
443
					actions: actions,
444
					columns: columns,
445
					moduleStore: myStore,
446
					gridOptions: {
447
						'class': 'appDetailsPageGridContent'
448
					}
449
				});
436
				});
450
				this._mainRegionContainer.addChild(this._installedAppsGrid);
437
				this._mainRegionContainer.addChild(usagePane);
451
			}
438
			}
439
		},
452
440
441
		_renderInstallationManagement: function() {
442
			var isSingleServerInstallation = this.app.isInstalled && this.app.installationData.length === 1;
443
			var actions = this.getActionButtons(isSingleServerInstallation);
444
			if (isSingleServerInstallation || this.app.isDocker) {
445
				this._renderSingleManagement(actions);
446
			} else {
447
				this._renderDomainwideManagement(actions);
448
			}
449
		},
450
451
		_renderSingleManagement: function(actions) {
452
			var header = new Text({
453
				content: _('Manage local installation'),
454
				'class': 'mainHeader'
455
			});
456
			this._mainRegionContainer.addChild(header);
457
			this._mainRegionContainer.own(header);
458
459
			var actionButtonContainer = new ContainerWidget({
460
				'class': 'appDetailsPageActions'
461
			});
462
			array.forEach(actions, function(action) {
463
				var button = new Button(action);
464
				actionButtonContainer.addChild(button);
465
				actionButtonContainer.own(button);
466
			});
467
			this._mainRegionContainer.addChild(actionButtonContainer);
468
			this._mainRegionContainer.own(actionButtonContainer);
469
		},
470
471
		_renderDomainwideManagement: function(actions) {
472
			var header = new Text({
473
				content: _('Manage domain wide installations'),
474
				'class': 'mainHeader'
475
			});
476
			this._mainRegionContainer.addChild(header);
477
			this._mainRegionContainer.own(header);
478
479
			var columns = [{
480
				name: 'server',
481
				label: _('Server')
482
			}, {
483
				name: 'appStatus',
484
				label: _('Status')
485
			}];
486
487
			var myStore = new Observable(new Memory({
488
				data: this.app.getHosts()
489
			}));
490
			this._installedAppsGrid = new adaptedGrid({
491
				'class': 'appDetailsPageActions',
492
				actions: actions,
493
				columns: columns,
494
				moduleStore: myStore,
495
				gridOptions: {
496
					'class': 'appDetailsPageActionsContent'
497
				}
498
			});
499
			this._mainRegionContainer.addChild(this._installedAppsGrid);
500
			this._mainRegionContainer.own(this._installedAppsGrid);
501
		},
502
503
		_renderDetailsPane: function(isAppInstalled) {
453
			this._detailsContainer = new ContainerWidget({
504
			this._detailsContainer = new ContainerWidget({
454
				'class': 'detailsContainer'
505
				'class': 'detailsContainer'
455
			});
506
			});
456
457
			var descriptionContainer = new ContainerWidget({
507
			var descriptionContainer = new ContainerWidget({
458
				'class': 'descriptionContainer'
508
				'class': 'descriptionContainer'
459
			});
509
			});
460
			var longDescCSSClass = _getCSSClass4TextLength(this.app.longDescription);
510
			var longDescCSSClass = this._getCSSClass4TextLength(this.app.longDescription);
461
			domClass.add(domConstruct.create('div', {
511
			domClass.add(domConstruct.create('div', {
462
				innerHTML: this.app.longDescription
512
				innerHTML: this.app.longDescription
463
			}, descriptionContainer.domNode), longDescCSSClass);
513
			}, descriptionContainer.domNode), longDescCSSClass);
 Lines 467-473    Link Here 
467
				var styleContainer = new ContainerWidget({
517
				var styleContainer = new ContainerWidget({
468
					'class': 'carouselWrapper'
518
					'class': 'carouselWrapper'
469
				});
519
				});
470
471
				var urls = array.map(this.app.thumbnails, function(ithumb) {
520
				var urls = array.map(this.app.thumbnails, function(ithumb) {
472
					return {
521
					return {
473
						src: ithumb
522
						src: ithumb
 Lines 480-501    Link Here 
480
				this._detailsContainer.addChild(styleContainer);
529
				this._detailsContainer.addChild(styleContainer);
481
			}
530
			}
482
531
483
			// for an uninstalled app show details (open TitlePane) at the top of main
484
			// otherwise close the Titlepane and move it under the grid
485
			var isOpen = true;
486
			if (this.app.isInstalled || this.app.getHosts().length) {
487
				isOpen = false;
488
			}
489
			var detailsPane = new TitlePane({
532
			var detailsPane = new TitlePane({
490
				open: isOpen,
533
				open: !isAppInstalled,
491
				//class: 'installedAppDetailsPane',
534
				//class: 'installedAppDetailsPane',
492
				title: _('Details'),
535
				title: _('Details'),
493
				content: this._detailsContainer,
536
				content: this._detailsContainer,
494
				'class': 'appDetailsPane'
537
				'class': 'appDetailsPane'
495
			});
538
			});
496
			this._mainRegionContainer.addChild(detailsPane, isOpen ? 0 : null);
539
			this._mainRegionContainer.addChild(detailsPane, isAppInstalled ? null : 0);
540
		},
497
541
498
			//footer
542
		_getCSSClass4TextLength: function(text) {
543
			var cssClass = '';
544
			array.forEach([400, 500, 600, 800], function(ilength) {
545
				if (text.length > ilength) {
546
					cssClass = 'textLongerThan' + ilength + 'Chars';
547
				}
548
			});
549
			return cssClass;
550
		},
551
552
		_renderFooter: function() {
499
			//TODO just for testing
553
			//TODO just for testing
500
			domConstruct.empty(this._footer.domNode);
554
			domConstruct.empty(this._footer.domNode);
501
555
 Lines 551-563    Link Here 
551
					});
605
					});
552
					for (var i = 0; i < rating.value; i++) {
606
					for (var i = 0; i < rating.value; i++) {
553
						domConstruct.create('div', {
607
						domConstruct.create('div', {
554
								'class': 'umcAppRatingIcon',
608
								'class': 'umcAppRatingIcon'
555
							}, ratingText.domNode
609
							}, ratingText.domNode
556
						);
610
						);
557
					}
611
					}
558
					domConstruct.create('div', {
612
					domConstruct.create('div', {
559
							'class': 'umcAppRatingText',
613
							'class': 'umcAppRatingText',
560
							textContent: rating.label,
614
							textContent: rating.label
561
						}, ratingText.domNode
615
						}, ratingText.domNode
562
					);
616
					);
563
					domConstruct.create('div', {
617
					domConstruct.create('div', {
 Lines 579-585    Link Here 
579
					footerRight.addChild(ratingText);
633
					footerRight.addChild(ratingText);
580
				});
634
				});
581
			}
635
			}
582
			domStyle.set(this._main.domNode, 'margin-bottom', '2em');
583
		},
636
		},
584
637
585
		openShop: function() {
638
		openShop: function() {
 Lines 1099-1110    Link Here 
1099
		},
1152
		},
1100
1153
1101
		_detailFieldCustomVendor: function() {
1154
		_detailFieldCustomVendor: function() {
1102
			var vendor = this.app.vendor;
1155
			var vendor = this.app.vendor || this.app.maintainer;
1103
			var website = this.app.websiteVendor;
1156
			var website = this.app.websiteVendor;
1104
			if (vendor && website) {
1157
			if (vendor && website) {
1105
				return '<a href="' + website + '" target="_blank">' + vendor + '</a>';
1158
				return '<div><a href="' + website + '" target="_blank">' + vendor + '</a></div>';
1106
			} else if (vendor) {
1159
			} else if (vendor) {
1107
				return vendor;
1160
				return '<div>' + vendor + '</div>';
1108
			}
1161
			}
1109
		},
1162
		},
1110
1163
 Lines 1158-1171    Link Here 
1158
				var categoriesContainerNode = domConstruct.create('div', {
1211
				var categoriesContainerNode = domConstruct.create('div', {
1159
					'class': 'categoryContainer'
1212
					'class': 'categoryContainer'
1160
				});
1213
				});
1161
				this.app.categories.forEach(lang.hitch(this, function(category) {
1214
				if (this.moduleID === 'appcenter') {
1162
					var categoryButton = domConstruct.create('button', {
1215
					this.app.categories.forEach(lang.hitch(this, function(category) {
1163
						textContent: _(category),
1216
						var categoryButton = domConstruct.create('button', {
1164
						onclick: lang.hitch(this, function() { this.onBack(category); }),
1217
							textContent: _(category),
1165
						'class': 'categoryButton'
1218
							onclick: lang.hitch(this, function() { this.onBack(category); }),
1166
					});
1219
							'class': 'categoryButton'
1167
					domConstruct.place(categoryButton, categoriesContainerNode);
1220
						});
1168
				}));
1221
						domConstruct.place(categoryButton, categoriesContainerNode);
1222
					}));
1223
				} else {
1224
					this.app.categories.forEach(lang.hitch(this, function(category) {
1225
						var categoryButton = domConstruct.create('span', {
1226
							textContent: _(category),
1227
							'class': 'categorySpan'
1228
						});
1229
						domConstruct.place(categoryButton, categoriesContainerNode);
1230
					}));
1231
				}
1169
				return categoriesContainerNode;
1232
				return categoriesContainerNode;
1170
			}
1233
			}
1171
		},
1234
		},

Return to bug 40116