Skip to content

Commit

Permalink
Merge a352a6d into f634e3f
Browse files Browse the repository at this point in the history
  • Loading branch information
Allison Gruninger committed Sep 19, 2018
2 parents f634e3f + a352a6d commit a347115
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 5 deletions.
25 changes: 23 additions & 2 deletions client/src/app/function/function-new/function-new.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,28 @@

<app-edit-mode-warning [context]="context"></app-edit-mode-warning>

<div *ngIf="functionsInfo" [fnWriteAccess]="context">
<ng-container *ngIf="needsWorkerRuntime">
<div class="runtimeStackTitle">
<img [src]="createCardStyles.other.icon" [style.background-color]="createCardStyles.other.color"/>
<h1>{{ 'functionAppRuntimeStackTitle' | translate }}</h1>
</div>
<div>
<h3>{{ 'functionAppRuntimeStackDescription' | translate }}</h3>
</div>
<div class="search-and-sort">
{{ 'functionRuntimeStackLabel' | translate }}
<drop-down class="tpicker-dropdown"
[options]="possibleRuntimes"
(value)="onRuntimeChanged($event)"
attr.aria-label="{{ 'functionRuntimeStackLabel' | translate }}">
</drop-down>
<button class="custom-button"
(click)="setRuntime()">{{ 'Go' | translate }}
</button>
</div>
</ng-container>

<div *ngIf="functionsInfo && !needsWorkerRuntime" [fnWriteAccess]="context">

<div class="choose">
<h2>{{ 'functionNew_chooseTemplate' | translate }}</h2>
Expand Down Expand Up @@ -46,7 +67,7 @@ <h2>{{ 'functionNew_chooseTemplate' | translate }}</h2>
attr.aria-label="{{'templatePicker_scenario' | translate}}">
</drop-down>

<div *ngIf="runtimeVersion === 'V1'">
<div *ngIf="runtimeVersion === 'V1' && !functionAppLanguage">
{{ 'experimentalLanguageSupport' | translate }}
<slide-toggle class="language-toggle"
[on]="showExperimentalLanguages"
Expand Down
13 changes: 13 additions & 0 deletions client/src/app/function/function-new/function-new.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ input.input-error {
padding-bottom:10px;
}

.runtimeStackTitle {
padding-bottom: 15px;
border-bottom: $border;
img {
display: inline-block;
height: 40px;
width: 40px;
margin-right: 15px;
padding: 5px;
float: left;
}
}

drop-down{
display: inline-block;
}
Expand Down
52 changes: 49 additions & 3 deletions client/src/app/function/function-new/function-new.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ export class FunctionNewComponent extends FunctionAppContextComponent implements
public allExperimentalLanguages = ['Bash', 'Batch', 'PHP', 'PowerShell', 'Python', 'TypeScript'];
public appSettingsArm: ArmObj<ApplicationSettings>;
public functionAppLanguage: string;
public templates: FunctionTemplate[];
public needsWorkerRuntime: boolean;
public runtime: string;

public possibleRuntimes: DropDownElement<string>[] =
[{
displayLabel: 'C#',
value: 'dotnet',
},
{
displayLabel: 'JavaScript',
value: 'node',
}];

public createCardStyles = {
'blob': { color: '#1E5890', icon: 'image/blob.svg' },
Expand Down Expand Up @@ -172,7 +185,8 @@ export class FunctionNewComponent extends FunctionAppContextComponent implements
this._functionAppService.getRuntimeGeneration(this.context),
this._siteService.getAppSettings(this.context.site.id),
this._functionAppService.getBindingConfig(this.context),
this._functionAppService.getTemplates(this.context));
this._functionAppService.getTemplates(this.context),
this._functionAppService.getWorkerRuntimeRequired(this.context));
})
.do(null, e => {
this._logService.error(LogCategories.functionNew, '/load-functions-cards-failure', e);
Expand All @@ -182,6 +196,8 @@ export class FunctionNewComponent extends FunctionAppContextComponent implements
this.runtimeVersion = tuple[1];
this.appSettingsArm = tuple[2].result;
this.bindings = tuple[3].result.bindings;
this.templates = tuple[4].result;
this.needsWorkerRuntime = tuple[5];

if (this.action && this.functionsInfo && !this.selectedTemplate) {
this.selectedTemplateId = this.action.templateId;
Expand All @@ -190,10 +206,18 @@ export class FunctionNewComponent extends FunctionAppContextComponent implements
if (this.appSettingsArm.properties.hasOwnProperty(Constants.functionsWorkerRuntimeAppSettingsName)) {
const workerRuntime = this.appSettingsArm.properties[Constants.functionsWorkerRuntimeAppSettingsName];
this.functionAppLanguage = WorkerRuntimeLanguages[workerRuntime];
this.allExperimentalLanguages = [];
if (!this.functionAppLanguage) {
// this is if workerRuntime is set, but value is invalid
this.needsWorkerRuntime = true;
} else {
// workerRuntime is valid
this.needsWorkerRuntime = false;
}
}

this._buildCreateCardTemplates(tuple[4].result);
if (!this.needsWorkerRuntime) {
this._buildCreateCardTemplates(this.templates);
}
this._globalStateService.clearBusyState();
});
}
Expand Down Expand Up @@ -351,6 +375,28 @@ export class FunctionNewComponent extends FunctionAppContextComponent implements
this.category = this._translateService.instant('temp_category_all');
}

onRuntimeChanged(runtime: string) {
this.runtime = runtime;
}

setRuntime() {
this._globalStateService.setBusyState();

this.appSettingsArm.properties[Constants.functionsWorkerRuntimeAppSettingsName] = this.runtime;

this._siteService.updateAppSettings(this.context.site.id, this.appSettingsArm)
.do(null, e => {
this._globalStateService.clearBusyState();
this.showComponentError(e);
})
.subscribe(() => {
this.functionAppLanguage = WorkerRuntimeLanguages[this.runtime];
this.needsWorkerRuntime = false;
this._buildCreateCardTemplates(this.templates);
this._globalStateService.clearBusyState();
});
}

switchExperimentalLanguagesOption() {
this.showExperimentalLanguages = !this.showExperimentalLanguages;
this.createCards.forEach(card => {
Expand Down
30 changes: 30 additions & 0 deletions client/src/app/shared/Utilities/runtime-versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export class RuntimeVersions {

public static getRuntimeParts(exactRuntime: string) {
return exactRuntime.split('.');
}

public static majorVersion(exactRuntime: string) {
const parts = this.getRuntimeParts(exactRuntime);
if (parts.length > 0) {
return Number(parts[0]);
}
return null;
}

public static minorVersion(exactRuntime: string) {
const parts = this.getRuntimeParts(exactRuntime);
if (parts.length > 2) {
return Number(parts[2]);
}
return null;
}

public static workerRuntimeRequired(exactRuntime: string) {
const minorVersion = this.minorVersion(exactRuntime);
if (minorVersion) {
return minorVersion >= 12050;
}
return false;
}
}
4 changes: 4 additions & 0 deletions client/src/app/shared/models/portal-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,10 @@
public static swapDiffNotSet = 'swapDiffNotSet';
public static extensionUninstallError = 'extensionUninstallError';
public static v2_preview_label = 'v2_preview_label';
public static functionAppRuntimeStackTitle = 'functionAppRuntimeStackTitle';
public static functionAppRuntimeStackDescription = 'functionAppRuntimeStackDescription';
public static functionRuntimeStackLabel = 'functionRuntimeStackLabel';
public static Go = 'Go';
public static containerACRRegistry = 'containerACRRegistry';
public static containerACRImage = 'containerACRImage';
public static containerACRTag = 'containerACRTag';
Expand Down
13 changes: 13 additions & 0 deletions client/src/app/shared/services/function-app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { Templates } from './../../function/embedded/temp-templates';
import { SiteService } from './site.service';
import { ExtensionJobsStatus } from '../models/extension-jobs-status';
import { ExtensionInfo, ExtensionsJson } from 'app/shared/models/extension-info';
import { RuntimeVersions } from 'app/shared/Utilities/runtime-versions';

type Result<T> = Observable<HttpResult<T>>;
@Injectable()
Expand Down Expand Up @@ -586,6 +587,18 @@ export class FunctionAppService {
.map(r => r.json() as HostStatus));
}

getWorkerRuntimeRequired(context: FunctionAppContext): Observable<boolean> {
return this.getFunctionHostStatus(context)
.map(r => {
if (r.isSuccessful) {
if (RuntimeVersions.workerRuntimeRequired(r.result.version)) {
return true;
}
}
return false;
});
}

getLogs(context: FunctionAppContext, fi: FunctionInfo, range?: number, force: boolean = false): Result<string> {
const url = context.urlTemplates.getFunctionLogUrl(fi.name);

Expand Down
12 changes: 12 additions & 0 deletions server/Resources/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -4039,6 +4039,18 @@ Set to "External URL" to use an API definition that is hosted elsewhere.</value>
<data name="v2_preview_label" xml:space="preserve">
<value>~2 (Preview)</value>
</data>
<data name="functionAppRuntimeStackTitle" xml:space="preserve">
<value>Function App runtime stack</value>
</data>
<data name="functionAppRuntimeStackDescription" xml:space="preserve">
<value>Function Apps v2 are now single language. Please set the runtime stack before adding functions to you app.</value>
</data>
<data name="functionRuntimeStackLabel" xml:space="preserve">
<value>Function Runtime stack</value>
</data>
<data name="Go" xml:space="preserve">
<value>Go</value>
</data>
<data name="containerACRRegistry" xml:space="preserve">
<value>Registry</value>
</data>
Expand Down

0 comments on commit a347115

Please sign in to comment.