Improve layout of actions in security group tab.

--- src/openstack/openstack-security-groups/SecurityGroupsList.tsx
+++ src/openstack/openstack-security-groups/SecurityGroupsList.tsx
@@ -19,10 +19,12 @@
         {
           title: translate('State'),
           render: ({ row }) => <ResourceState resource={row} />,
+          className: 'col-sm-2',
         },
         {
           title: translate('Actions'),
           render: ({ row }) => <ResourceRowActions resource={row} />,
+          className: 'col-sm-2',
         },
       ]}
       verboseName={translate('security groups')}

<|original_code|>
import * as React from 'react';

import { NestedListActions } from '@waldur/resource/actions/NestedListActions';
import { ResourceRowActions } from '@waldur/resource/actions/ResourceRowActions';
import { ResourceName } from '@waldur/resource/ResourceName';
import { ResourceState } from '@waldur/resource/state/ResourceState';
import { Table, connectTable, createFetcher } from '@waldur/table-react';

const TableComponent = props => {
  const { translate } = props;
  return (
    <Table
      {...props}
      columns={[
        {
          title: translate('Name'),
          render: ({ row }) => <ResourceName resource={row} />,
        },
        {
          title: translate('State'),
          render: ({ row }) => <ResourceState resource={row} />,
        },
        {
          title: translate('Actions'),
          render: ({ row }) => <ResourceRowActions resource={row} />,
        },
      ]}
      verboseName={translate('security groups')}
      actions={
        <NestedListActions resource={props.resource} tab="security_groups" />
      }
    />
  );
};

const TableOptions = {
  table: 'openstack-security-groups',
  fetchData: createFetcher('openstack-security-groups'),
  mapPropsToFilter: props => ({
    tenant_uuid: props.resource.uuid,
  }),
};

export const SecurityGroupsList = connectTable(TableOptions)(TableComponent);

<|edits_diff|>
--- src/openstack/openstack-security-groups/SecurityGroupsList.tsx
+++ src/openstack/openstack-security-groups/SecurityGroupsList.tsx
@@ -19,6 +19,7 @@
         {
           title: translate('State'),
           render: ({ row }) => <ResourceState resource={row} />,
+          className: 'col-sm-2',
         },
         {
           title: translate('Actions'),
<|current_version|>
import * as React from 'react';

import { NestedListActions } from '@waldur/resource/actions/NestedListActions';
import { ResourceRowActions } from '@waldur/resource/actions/ResourceRowActions';
import { ResourceName } from '@waldur/resource/ResourceName';
import { ResourceState } from '@waldur/resource/state/ResourceState';
import { Table, connectTable, createFetcher } from '@waldur/table-react';

const TableComponent = props => {
  const { translate } = props;
  return (
    <Table
      {...props}
      columns={[
        {
          title: translate('Name'),
          render: ({ row }) => <ResourceName resource={row} />,
        },
        {
          title: translate('State'),
          render: ({ row }) => <ResourceState resource={row} />,
          className: 'col-sm-2',
        },
        {
          title: translate('Actions'),
          render: ({ row }) => <ResourceRowActions resource={row} />,
        },
      ]}
      verboseName={translate('security groups')}
      actions={
        <NestedListActions resource={props.resource} tab="security_groups" />
      }
    />
  );
};

const TableOptions = {
  table: 'openstack-security-groups',
  fetchData: createFetcher('openstack-security-groups'),
  mapPropsToFilter: props => ({
    tenant_uuid: props.resource.uuid,
  }),
};

export const SecurityGroupsList = connectTable(TableOptions)(TableComponent);

<|next_version|>
import * as React from 'react';

import { NestedListActions } from '@waldur/resource/actions/NestedListActions';
import { ResourceRowActions } from '@waldur/resource/actions/ResourceRowActions';
import { ResourceName } from '@waldur/resource/ResourceName';
import { ResourceState } from '@waldur/resource/state/ResourceState';
import { Table, connectTable, createFetcher } from '@waldur/table-react';

const TableComponent = props => {
  const { translate } = props;
  return (
    <Table
      {...props}
      columns={[
        {
          title: translate('Name'),
          render: ({ row }) => <ResourceName resource={row} />,
        },
        {
          title: translate('State'),
          render: ({ row }) => <ResourceState resource={row} />,
          className: 'col-sm-2',
        },
        {
          title: translate('Actions'),
          render: ({ row }) => <ResourceRowActions resource={row} />,
          className: 'col-sm-2',
        },
      ]}
      verboseName={translate('security groups')}
      actions={
        <NestedListActions resource={props.resource} tab="security_groups" />
      }
    />
  );
};

const TableOptions = {
  table: 'openstack-security-groups',
  fetchData: createFetcher('openstack-security-groups'),
  mapPropsToFilter: props => ({
    tenant_uuid: props.resource.uuid,
  }),
};

export const SecurityGroupsList = connectTable(TableOptions)(TableComponent);


Add width for the item

Add width for the item

--- src/app/carousel/components/ngx-agile-slider-item.component.ts
+++ src/app/carousel/components/ngx-agile-slider-item.component.ts
@@ -18,6 +18,7 @@
    * additional classes for li
    */
   @Input() additionalClasses: string[];
+  @Input() width: string;

   @ViewChild('sliderItem') sliderItem: ElementRef;

@@ -30,5 +31,9 @@
         this.sliderItem.nativeElement.classList.add(this.additionalClasses[i]);
       }
     }
+
+    if (this.width) {
+      this.sliderItem.nativeElement.style.width = this.width;
+    }
   }
 }

<|original_code|>
import { AfterViewInit, Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';

/**
 * This component represents the slide item.
 */
@Component({
  moduleId: module.id,
  selector: 'ngx-agile-slider-item',
  template: `
    <li #sliderItem class="ngx-agile-slider-item variablewidth">
      <ng-content></ng-content>
    </li>
  `,
  encapsulation: ViewEncapsulation.None
})
export class SliderItemComponent implements AfterViewInit {
  /**
   * additional classes for li
   */
  @Input() additionalClasses: string[];

  @ViewChild('sliderItem') sliderItem: ElementRef;

  /**
   * Called after the view was initialized. Adds the additional classes
   */
  public ngAfterViewInit() {
    if (this.additionalClasses) {
      for (let i = 0; i < this.additionalClasses.length; i++) {
        this.sliderItem.nativeElement.classList.add(this.additionalClasses[i]);
      }
    }
  }
}

<|edits_diff|>
--- src/app/carousel/components/ngx-agile-slider-item.component.ts
+++ src/app/carousel/components/ngx-agile-slider-item.component.ts
@@ -18,6 +18,7 @@
    * additional classes for li
    */
   @Input() additionalClasses: string[];
+  @Input() width: string;

   @ViewChild('sliderItem') sliderItem: ElementRef;

<|current_version|>
import { AfterViewInit, Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';

/**
 * This component represents the slide item.
 */
@Component({
  moduleId: module.id,
  selector: 'ngx-agile-slider-item',
  template: `
    <li #sliderItem class="ngx-agile-slider-item variablewidth">
      <ng-content></ng-content>
    </li>
  `,
  encapsulation: ViewEncapsulation.None
})
export class SliderItemComponent implements AfterViewInit {
  /**
   * additional classes for li
   */
  @Input() additionalClasses: string[];
  @Input() width: string;

  @ViewChild('sliderItem') sliderItem: ElementRef;

  /**
   * Called after the view was initialized. Adds the additional classes
   */
  public ngAfterViewInit() {
    if (this.additionalClasses) {
      for (let i = 0; i < this.additionalClasses.length; i++) {
        this.sliderItem.nativeElement.classList.add(this.additionalClasses[i]);
      }
    }
  }
}

<|next_version|>
import { AfterViewInit, Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';

/**
 * This component represents the slide item.
 */
@Component({
  moduleId: module.id,
  selector: 'ngx-agile-slider-item',
  template: `
    <li #sliderItem class="ngx-agile-slider-item variablewidth">
      <ng-content></ng-content>
    </li>
  `,
  encapsulation: ViewEncapsulation.None
})
export class SliderItemComponent implements AfterViewInit {
  /**
   * additional classes for li
   */
  @Input() additionalClasses: string[];
  @Input() width: string;

  @ViewChild('sliderItem') sliderItem: ElementRef;

  /**
   * Called after the view was initialized. Adds the additional classes
   */
  public ngAfterViewInit() {
    if (this.additionalClasses) {
      for (let i = 0; i < this.additionalClasses.length; i++) {
        this.sliderItem.nativeElement.classList.add(this.additionalClasses[i]);
      }
    }

    if (this.width) {
      this.sliderItem.nativeElement.style.width = this.width;
    }
  }
}


Set page level locales service

Set page level locales service

--- app/src/app/pages/locale/locale-page.component.ts
+++ app/src/app/pages/locale/locale-page.component.ts
@@ -1,6 +1,9 @@
 import { Component, OnInit } from '@angular/core';

+import { LocalesService } from './../../locales/services/locales.service';
+
 @Component({
+    providers: [LocalesService],
     selector: 'locale-page',
     templateUrl: 'locale-page.component.html'
 })

<|original_code|>
import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'locale-page',
    templateUrl: 'locale-page.component.html'
})
export class LocalePage implements OnInit {
    ngOnInit() {

    }
}
<|edits_diff|>
--- app/src/app/pages/locale/locale-page.component.ts
+++ app/src/app/pages/locale/locale-page.component.ts
@@ -1,4 +1,6 @@
 import { Component, OnInit } from '@angular/core';
+
+import { LocalesService } from './../../locales/services/locales.service';

 @Component({
     selector: 'locale-page',
<|current_version|>
import { Component, OnInit } from '@angular/core';

import { LocalesService } from './../../locales/services/locales.service';

@Component({
    selector: 'locale-page',
    templateUrl: 'locale-page.component.html'
})
export class LocalePage implements OnInit {
    ngOnInit() {

    }
}
<|next_version|>
import { Component, OnInit } from '@angular/core';

import { LocalesService } from './../../locales/services/locales.service';

@Component({
    providers: [LocalesService],
    selector: 'locale-page',
    templateUrl: 'locale-page.component.html'
})
export class LocalePage implements OnInit {
    ngOnInit() {

    }
}


import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

class Crosshair extends PureComponent<Props> {
  public render() {
    return (
      <div className="crosshair-container">
        <div
          className="crosshair"
          style={{
            left: this.crosshairLeft,
            height: this.crosshairHeight,
            width: '1px',
          }}
        />
      </div>
    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)

import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'
import {ErrorHandling} from 'src/shared/decorators/errors'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

@ErrorHandling
class Crosshair extends PureComponent<Props> {
  public render() {
    return (
      <div className="crosshair-container">
        <div
          className="crosshair"
          style={{
            left: this.crosshairLeft,
            height: this.crosshairHeight,
            width: '1px',
          }}
        />
      </div>
    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)

Add ErrorHandling decorator to crosshairs

--- ui/src/shared/components/Crosshair.tsx
+++ ui/src/shared/components/Crosshair.tsx
@@ -1,6 +1,7 @@
 import React, {PureComponent} from 'react'
 import Dygraph from 'dygraphs'
 import {connect} from 'react-redux'
+import {ErrorHandling} from 'src/shared/decorators/errors'

 import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

@@ -10,6 +11,7 @@
   staticLegendHeight: number
 }

+@ErrorHandling
 class Crosshair extends PureComponent<Props> {
   public render() {
     return (

import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'
import {ErrorHandling} from 'src/shared/decorators/errors'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

class Crosshair extends PureComponent<Props> {
  public render() {
    return (
      <div className="crosshair-container">
        <div
          className="crosshair"
          style={{
            left: this.crosshairLeft,
            height: this.crosshairHeight,
            width: '1px',
          }}
        />
      </div>
    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)

<|original_code|>
import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

class Crosshair extends PureComponent<Props> {
  public render() {
    return (

    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)

<|edits_diff|>
--- ui/src/shared/components/Crosshair.tsx
+++ ui/src/shared/components/Crosshair.tsx
@@ -1,6 +1,7 @@
 import React, {PureComponent} from 'react'
 import Dygraph from 'dygraphs'
 import {connect} from 'react-redux'
+import {ErrorHandling} from 'src/shared/decorators/errors'

 import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

<|current_version|>
import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'
import {ErrorHandling} from 'src/shared/decorators/errors'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

class Crosshair extends PureComponent<Props> {
  public render() {
    return (

    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)

<|next_version|>
import React, {PureComponent} from 'react'
import Dygraph from 'dygraphs'
import {connect} from 'react-redux'
import {ErrorHandling} from 'src/shared/decorators/errors'

import {DYGRAPH_CONTAINER_XLABEL_MARGIN} from 'src/shared/constants'

interface Props {
  hoverTime: number
  dygraph: Dygraph
  staticLegendHeight: number
}

@ErrorHandling
class Crosshair extends PureComponent<Props> {
  public render() {
    return (

    )
  }

  private get crosshairLeft(): number {
    const {dygraph, hoverTime} = this.props
    const cursorOffset = 16
    return dygraph.toDomXCoord(hoverTime) + cursorOffset
  }

  private get crosshairHeight(): string {
    return `calc(100% - ${this.props.staticLegendHeight +
      DYGRAPH_CONTAINER_XLABEL_MARGIN}px)`
  }
}

const mapStateToProps = ({dashboardUI, annotations: {mode}}) => ({
  mode,
  hoverTime: +dashboardUI.hoverTime,
})

export default connect(mapStateToProps, null)(Crosshair)


Clone the propMetadata key as well

Clone the propMetadata key as well

--- src/index.ts
+++ src/index.ts
@@ -11,6 +11,7 @@

 	return function ConfigInitializerDecorator(targetConstructor: any) {
 		const metaInformation = getOwnMetadata('annotations', targetConstructor);
+		const propMetaInformation = getOwnMetadata('propMetadata', targetConstructor);
 		const designParamtypesInformation = getOwnMetadata('design:paramtypes', targetConstructor);
 		const parametersInformation = getOwnMetadata('parameters', targetConstructor);

@@ -25,6 +26,7 @@
 		}

 		defineMetadata('annotations', metaInformation, newConstructor);
+		defineMetadata('propMetadata', propMetaInformation, newConstructor);
 		defineMetadata('parameters', parametersInformation, newConstructor);
 		defineMetadata(
 			'design:paramtypes',

<|original_code|>
import { OpaqueToken, Inject } from '@angular/core';

export const CONFIG_INITIALIZER = new OpaqueToken('Config initializer');

export function ConfigInitializer<T>(config: T) {
	type ConfigInitializerType = (config: T) => void;

	const reflect: any = (window as any)['Reflect'];
	const getOwnMetadata: Function = reflect.getOwnMetadata;
	const defineMetadata: Function = reflect.defineMetadata;

	return function ConfigInitializerDecorator(targetConstructor: any) {
		const metaInformation = getOwnMetadata('annotations', targetConstructor);
		const designParamtypesInformation = getOwnMetadata('design:paramtypes', targetConstructor);
		const parametersInformation = getOwnMetadata('parameters', targetConstructor);

		function newConstructor(
			configInitializer: ConfigInitializerType,
			...args: any[],
		) {
			configInitializer(config);

			// tslint:disable-next-line:no-invalid-this
			return targetConstructor.apply(this, args);
		}

		defineMetadata('annotations', metaInformation, newConstructor);
		defineMetadata('parameters', parametersInformation, newConstructor);
		defineMetadata(
			'design:paramtypes',
			[
				new Inject(CONFIG_INITIALIZER),
				...designParamtypesInformation,
			],
			newConstructor,
		);

		newConstructor.prototype = targetConstructor.prototype;

		return newConstructor as typeof targetConstructor;
	};
}

<|edits_diff|>
--- src/index.ts
+++ src/index.ts
@@ -11,6 +11,7 @@

 	return function ConfigInitializerDecorator(targetConstructor: any) {
 		const metaInformation = getOwnMetadata('annotations', targetConstructor);
+		const propMetaInformation = getOwnMetadata('propMetadata', targetConstructor);
 		const designParamtypesInformation = getOwnMetadata('design:paramtypes', targetConstructor);
 		const parametersInformation = getOwnMetadata('parameters', targetConstructor);

<|current_version|>
import { OpaqueToken, Inject } from '@angular/core';

export const CONFIG_INITIALIZER = new OpaqueToken('Config initializer');

export function ConfigInitializer<T>(config: T) {
	type ConfigInitializerType = (config: T) => void;

	const reflect: any = (window as any)['Reflect'];
	const getOwnMetadata: Function = reflect.getOwnMetadata;
	const defineMetadata: Function = reflect.defineMetadata;

	return function ConfigInitializerDecorator(targetConstructor: any) {
		const metaInformation = getOwnMetadata('annotations', targetConstructor);
		const propMetaInformation = getOwnMetadata('propMetadata', targetConstructor);
		const designParamtypesInformation = getOwnMetadata('design:paramtypes', targetConstructor);
		const parametersInformation = getOwnMetadata('parameters', targetConstructor);

		function newConstructor(
			configInitializer: ConfigInitializerType,
			...args: any[],
		) {
			configInitializer(config);

			// tslint:disable-next-line:no-invalid-this
			return targetConstructor.apply(this, args);
		}

		defineMetadata('annotations', metaInformation, newConstructor);
		defineMetadata('parameters', parametersInformation, newConstructor);
		defineMetadata(
			'design:paramtypes',
			[
				new Inject(CONFIG_INITIALIZER),
				...designParamtypesInformation,
			],
			newConstructor,
		);

		newConstructor.prototype = targetConstructor.prototype;

		return newConstructor as typeof targetConstructor;
	};
}

<|next_version|>
import { OpaqueToken, Inject } from '@angular/core';

export const CONFIG_INITIALIZER = new OpaqueToken('Config initializer');

export function ConfigInitializer<T>(config: T) {
	type ConfigInitializerType = (config: T) => void;

	const reflect: any = (window as any)['Reflect'];
	const getOwnMetadata: Function = reflect.getOwnMetadata;
	const defineMetadata: Function = reflect.defineMetadata;

	return function ConfigInitializerDecorator(targetConstructor: any) {
		const metaInformation = getOwnMetadata('annotations', targetConstructor);
		const propMetaInformation = getOwnMetadata('propMetadata', targetConstructor);
		const designParamtypesInformation = getOwnMetadata('design:paramtypes', targetConstructor);
		const parametersInformation = getOwnMetadata('parameters', targetConstructor);

		function newConstructor(
			configInitializer: ConfigInitializerType,
			...args: any[],
		) {
			configInitializer(config);

			// tslint:disable-next-line:no-invalid-this
			return targetConstructor.apply(this, args);
		}

		defineMetadata('annotations', metaInformation, newConstructor);
		defineMetadata('propMetadata', propMetaInformation, newConstructor);
		defineMetadata('parameters', parametersInformation, newConstructor);
		defineMetadata(
			'design:paramtypes',
			[
				new Inject(CONFIG_INITIALIZER),
				...designParamtypesInformation,
			],
			newConstructor,
		);

		newConstructor.prototype = targetConstructor.prototype;

		return newConstructor as typeof targetConstructor;
	};
}


Add account reducer to root reducer.

Add account reducer to root reducer.

--- src/reducers.ts
+++ src/reducers.ts
@@ -3,6 +3,7 @@
 import { reducer as toastr } from 'react-redux-toastr';
 import { default as tab } from './reducers/tab';
 import { default as searchingActive } from './reducers/searchingActive';
+import { default as account } from './reducers/account';
 import { default as search } from './reducers/search';
 import { default as queue } from './reducers/queue';
 import { default as watchers } from './reducers/watchers';
@@ -21,6 +22,7 @@
   queue,
   search,
   toastr,
+  account,
   watchers,
   audioFiles,
   hitBlocklist,

<|original_code|>
import { RootState } from './types';
import { combineReducers } from 'redux';
import { reducer as toastr } from 'react-redux-toastr';
import { default as tab } from './reducers/tab';
import { default as searchingActive } from './reducers/searchingActive';
import { default as search } from './reducers/search';
import { default as queue } from './reducers/queue';
import { default as watchers } from './reducers/watchers';
import { default as searchOptions } from './reducers/searchOptions';
import { default as sortingOption } from './reducers/sortingOption';
import { default as hitBlocklist } from './reducers/hitBlocklist';
import { default as timeNextSearch } from './reducers/timeNextSearch';
import { default as waitingForMturk } from './reducers/waitingForMturk';
import { default as topticonSettings } from './reducers/topticonSettings';
import { default as requesterBlocklist } from './reducers/requesterBlocklist';
import { default as audioSettingsV1 } from './reducers/audioSettings';
import { default as audioFiles } from './reducers/audioFiles';

export const rootReducer = combineReducers<RootState>({
  tab,
  queue,
  search,
  toastr,
  watchers,
  audioFiles,
  hitBlocklist,
  searchOptions,
  sortingOption,
  timeNextSearch,
  audioSettingsV1,
  waitingForMturk,
  searchingActive,
  topticonSettings,
  requesterBlocklist
});

<|edits_diff|>
--- src/reducers.ts
+++ src/reducers.ts
@@ -3,6 +3,7 @@
 import { reducer as toastr } from 'react-redux-toastr';
 import { default as tab } from './reducers/tab';
 import { default as searchingActive } from './reducers/searchingActive';
+import { default as account } from './reducers/account';
 import { default as search } from './reducers/search';
 import { default as queue } from './reducers/queue';
 import { default as watchers } from './reducers/watchers';
<|current_version|>
import { RootState } from './types';
import { combineReducers } from 'redux';
import { reducer as toastr } from 'react-redux-toastr';
import { default as tab } from './reducers/tab';
import { default as searchingActive } from './reducers/searchingActive';
import { default as account } from './reducers/account';
import { default as search } from './reducers/search';
import { default as queue } from './reducers/queue';
import { default as watchers } from './reducers/watchers';
import { default as searchOptions } from './reducers/searchOptions';
import { default as sortingOption } from './reducers/sortingOption';
import { default as hitBlocklist } from './reducers/hitBlocklist';
import { default as timeNextSearch } from './reducers/timeNextSearch';
import { default as waitingForMturk } from './reducers/waitingForMturk';
import { default as topticonSettings } from './reducers/topticonSettings';
import { default as requesterBlocklist } from './reducers/requesterBlocklist';
import { default as audioSettingsV1 } from './reducers/audioSettings';
import { default as audioFiles } from './reducers/audioFiles';

export const rootReducer = combineReducers<RootState>({
  tab,
  queue,
  search,
  toastr,
  watchers,
  audioFiles,
  hitBlocklist,
  searchOptions,
  sortingOption,
  timeNextSearch,
  audioSettingsV1,
  waitingForMturk,
  searchingActive,
  topticonSettings,
  requesterBlocklist
});

<|next_version|>
import { RootState } from './types';
import { combineReducers } from 'redux';
import { reducer as toastr } from 'react-redux-toastr';
import { default as tab } from './reducers/tab';
import { default as searchingActive } from './reducers/searchingActive';
import { default as account } from './reducers/account';
import { default as search } from './reducers/search';
import { default as queue } from './reducers/queue';
import { default as watchers } from './reducers/watchers';
import { default as searchOptions } from './reducers/searchOptions';
import { default as sortingOption } from './reducers/sortingOption';
import { default as hitBlocklist } from './reducers/hitBlocklist';
import { default as timeNextSearch } from './reducers/timeNextSearch';
import { default as waitingForMturk } from './reducers/waitingForMturk';
import { default as topticonSettings } from './reducers/topticonSettings';
import { default as requesterBlocklist } from './reducers/requesterBlocklist';
import { default as audioSettingsV1 } from './reducers/audioSettings';
import { default as audioFiles } from './reducers/audioFiles';

export const rootReducer = combineReducers<RootState>({
  tab,
  queue,
  search,
  toastr,
  account,
  watchers,
  audioFiles,
  hitBlocklist,
  searchOptions,
  sortingOption,
  timeNextSearch,
  audioSettingsV1,
  waitingForMturk,
  searchingActive,
  topticonSettings,
  requesterBlocklist
});


Stop audio when new files are loaded

fix: Stop audio when new files are loaded

--- src/app/file-store/file-store.service.ts
+++ src/app/file-store/file-store.service.ts
@@ -19,6 +19,9 @@
     }

     set audioFile(file: File) {
+        if (this.audioPlayer.playing) {
+            this.audioPlayer.stop();
+        }
         this.$audioFileName = file.name;
         this.audioPlayer.audio = URL.createObjectURL(file);
     }
@@ -28,6 +31,9 @@
     }

     set chartFile(file: File) {
+        if (this.audioPlayer.playing) {
+            this.audioPlayer.stop();
+        }
         this.$chartFileName = file.name;
         const reader = new FileReader();
         reader.onload = () => {

<|original_code|>
import { Injectable } from '@angular/core';

import { AudioPlayerService } from '../audio-player/audio-player.service';
import { ChartFileImporterService } from '../chart-file/importer/chart-file-importer.service';

@Injectable()
export class FileStoreService {

    private $audioFileName: string;
    private $chartFileName: string;

    constructor(
        private audioPlayer: AudioPlayerService,
        private chartFileImporter: ChartFileImporterService) {
    }

    get audioFileName(): string {
        return this.$audioFileName;
    }

    set audioFile(file: File) {
        this.$audioFileName = file.name;
        this.audioPlayer.audio = URL.createObjectURL(file);
    }

    get chartFileName(): string {
        return this.$chartFileName;
    }

    set chartFile(file: File) {
        this.$chartFileName = file.name;
        const reader = new FileReader();
        reader.onload = () => {
            this.chartFileImporter.import(reader.result);
        };
        reader.readAsText(file);
    }
}

<|edits_diff|>
--- src/app/file-store/file-store.service.ts
+++ src/app/file-store/file-store.service.ts
@@ -19,6 +19,9 @@
     }

     set audioFile(file: File) {
+        if (this.audioPlayer.playing) {
+            this.audioPlayer.stop();
+        }
         this.$audioFileName = file.name;
         this.audioPlayer.audio = URL.createObjectURL(file);
     }
<|current_version|>
import { Injectable } from '@angular/core';

import { AudioPlayerService } from '../audio-player/audio-player.service';
import { ChartFileImporterService } from '../chart-file/importer/chart-file-importer.service';

@Injectable()
export class FileStoreService {

    private $audioFileName: string;
    private $chartFileName: string;

    constructor(
        private audioPlayer: AudioPlayerService,
        private chartFileImporter: ChartFileImporterService) {
    }

    get audioFileName(): string {
        return this.$audioFileName;
    }

    set audioFile(file: File) {
        if (this.audioPlayer.playing) {
            this.audioPlayer.stop();
        }
        this.$audioFileName = file.name;
        this.audioPlayer.audio = URL.createObjectURL(file);
    }

    get chartFileName(): string {
        return this.$chartFileName;
    }

    set chartFile(file: File) {
        this.$chartFileName = file.name;
        const reader = new FileReader();
        reader.onload = () => {
            this.chartFileImporter.import(reader.result);
        };
        reader.readAsText(file);
    }
}

<|next_version|>
import { Injectable } from '@angular/core';

import { AudioPlayerService } from '../audio-player/audio-player.service';
import { ChartFileImporterService } from '../chart-file/importer/chart-file-importer.service';

@Injectable()
export class FileStoreService {

    private $audioFileName: string;
    private $chartFileName: string;

    constructor(
        private audioPlayer: AudioPlayerService,
        private chartFileImporter: ChartFileImporterService) {
    }

    get audioFileName(): string {
        return this.$audioFileName;
    }

    set audioFile(file: File) {
        if (this.audioPlayer.playing) {
            this.audioPlayer.stop();
        }
        this.$audioFileName = file.name;
        this.audioPlayer.audio = URL.createObjectURL(file);
    }

    get chartFileName(): string {
        return this.$chartFileName;
    }

    set chartFile(file: File) {
        if (this.audioPlayer.playing) {
            this.audioPlayer.stop();
        }
        this.$chartFileName = file.name;
        const reader = new FileReader();
        reader.onload = () => {
            this.chartFileImporter.import(reader.result);
        };
        reader.readAsText(file);
    }
}


Add end and home key controls

Add end and home key controls

--- src/ts/uiutils.ts
+++ src/ts/uiutils.ts
@@ -28,6 +28,9 @@
     UpArrow = 38,
     RightArrow = 39,
     DownArrow = 40,
+
     Space = 32,
+    End = 35,
+    Home = 36,
   }
 }

<|original_code|>
import {Component, ComponentConfig} from './components/component';
import {Container} from './components/container';

export namespace UIUtils {
  export interface TreeTraversalCallback {
    (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>): void;
  }

  export function traverseTree(component: Component<ComponentConfig>, visit: TreeTraversalCallback): void {
    let recursiveTreeWalker = (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>) => {
      visit(component, parent);

      // If the current component is a container, visit it's children
      if (component instanceof Container) {
        for (let childComponent of component.getComponents()) {
          recursiveTreeWalker(childComponent, component);
        }
      }
    };

    // Walk and configure the component tree
    recursiveTreeWalker(component);
  }

  // From: https://github.com/nfriend/ts-keycode-enum/blob/master/Key.enum.ts
  export enum KeyCode {
    LeftArrow = 37,
    UpArrow = 38,
    RightArrow = 39,
    DownArrow = 40,
    Space = 32,
  }
}

<|edits_diff|>
--- src/ts/uiutils.ts
+++ src/ts/uiutils.ts
@@ -28,6 +28,7 @@
     UpArrow = 38,
     RightArrow = 39,
     DownArrow = 40,
+
     Space = 32,
   }
 }
<|current_version|>
import {Component, ComponentConfig} from './components/component';
import {Container} from './components/container';

export namespace UIUtils {
  export interface TreeTraversalCallback {
    (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>): void;
  }

  export function traverseTree(component: Component<ComponentConfig>, visit: TreeTraversalCallback): void {
    let recursiveTreeWalker = (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>) => {
      visit(component, parent);

      // If the current component is a container, visit it's children
      if (component instanceof Container) {
        for (let childComponent of component.getComponents()) {
          recursiveTreeWalker(childComponent, component);
        }
      }
    };

    // Walk and configure the component tree
    recursiveTreeWalker(component);
  }

  // From: https://github.com/nfriend/ts-keycode-enum/blob/master/Key.enum.ts
  export enum KeyCode {
    LeftArrow = 37,
    UpArrow = 38,
    RightArrow = 39,
    DownArrow = 40,

    Space = 32,
  }
}

<|next_version|>
import {Component, ComponentConfig} from './components/component';
import {Container} from './components/container';

export namespace UIUtils {
  export interface TreeTraversalCallback {
    (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>): void;
  }

  export function traverseTree(component: Component<ComponentConfig>, visit: TreeTraversalCallback): void {
    let recursiveTreeWalker = (component: Component<ComponentConfig>, parent?: Component<ComponentConfig>) => {
      visit(component, parent);

      // If the current component is a container, visit it's children
      if (component instanceof Container) {
        for (let childComponent of component.getComponents()) {
          recursiveTreeWalker(childComponent, component);
        }
      }
    };

    // Walk and configure the component tree
    recursiveTreeWalker(component);
  }

  // From: https://github.com/nfriend/ts-keycode-enum/blob/master/Key.enum.ts
  export enum KeyCode {
    LeftArrow = 37,
    UpArrow = 38,
    RightArrow = 39,
    DownArrow = 40,

    Space = 32,
    End = 35,
    Home = 36,
  }
}


Add portable text diff resolver

[field] Add portable text diff resolver

--- packages/@sanity/field/src/diff/resolve/diffResolver.ts
+++ packages/@sanity/field/src/diff/resolve/diffResolver.ts
@@ -1,6 +1,7 @@
 import {DatetimeFieldDiff} from '../components/datetime'
 import {UrlFieldDiff} from '../components/url'
 import {SlugFieldDiff} from '../components/slug'
+import {isPTSchemaType, PTDiff} from '../components/portableText'
 import {DiffComponentResolver} from '../types'

 export const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
@@ -17,5 +18,9 @@
     return SlugFieldDiff
   }

+  if (isPTSchemaType(schemaType)) {
+    return PTDiff
+  }
+
   return undefined
 }

<|original_code|>
import {DatetimeFieldDiff} from '../components/datetime'
import {UrlFieldDiff} from '../components/url'
import {SlugFieldDiff} from '../components/slug'
import {DiffComponentResolver} from '../types'

export const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
  // datetime or date
  if (['datetime', 'date'].includes(schemaType.name)) {
    return DatetimeFieldDiff
  }

  if (schemaType.name === 'url') {
    return UrlFieldDiff
  }

  if (schemaType.name === 'slug') {
    return SlugFieldDiff
  }

  return undefined
}

<|edits_diff|>
--- packages/@sanity/field/src/diff/resolve/diffResolver.ts
+++ packages/@sanity/field/src/diff/resolve/diffResolver.ts
@@ -1,6 +1,7 @@
 import {DatetimeFieldDiff} from '../components/datetime'
 import {UrlFieldDiff} from '../components/url'
 import {SlugFieldDiff} from '../components/slug'
+import {isPTSchemaType, PTDiff} from '../components/portableText'
 import {DiffComponentResolver} from '../types'

 export const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
<|current_version|>
import {DatetimeFieldDiff} from '../components/datetime'
import {UrlFieldDiff} from '../components/url'
import {SlugFieldDiff} from '../components/slug'
import {isPTSchemaType, PTDiff} from '../components/portableText'
import {DiffComponentResolver} from '../types'

export const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
  // datetime or date
  if (['datetime', 'date'].includes(schemaType.name)) {
    return DatetimeFieldDiff
  }

  if (schemaType.name === 'url') {
    return UrlFieldDiff
  }

  if (schemaType.name === 'slug') {
    return SlugFieldDiff
  }

  return undefined
}

<|next_version|>
import {DatetimeFieldDiff} from '../components/datetime'
import {UrlFieldDiff} from '../components/url'
import {SlugFieldDiff} from '../components/slug'
import {isPTSchemaType, PTDiff} from '../components/portableText'
import {DiffComponentResolver} from '../types'

export const diffResolver: DiffComponentResolver = function diffResolver({schemaType}) {
  // datetime or date
  if (['datetime', 'date'].includes(schemaType.name)) {
    return DatetimeFieldDiff
  }

  if (schemaType.name === 'url') {
    return UrlFieldDiff
  }

  if (schemaType.name === 'slug') {
    return SlugFieldDiff
  }

  if (isPTSchemaType(schemaType)) {
    return PTDiff
  }

  return undefined
}


Add codehighlight to setup doc

Add codehighlight to setup doc

--- showcase/setup/setup.module.ts
+++ showcase/setup/setup.module.ts
@@ -2,10 +2,12 @@
 import {CommonModule} from '@angular/common';
 import {SetupComponent} from './setup.component';
 import {SetupRoutingModule} from './setup-routing.module';
+import {CodeHighlighterModule} from '../../components/codehighlighter/codehighlighter';

 @NgModule({
   imports: [
     CommonModule,
+    CodeHighlighterModule,
     SetupRoutingModule
   ],
   declarations: [

<|original_code|>
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {SetupComponent} from './setup.component';
import {SetupRoutingModule} from './setup-routing.module';

@NgModule({
  imports: [
    CommonModule,
    SetupRoutingModule
  ],
  declarations: [
    SetupComponent
  ]
})
export class SetupModule {}
<|edits_diff|>
--- showcase/setup/setup.module.ts
+++ showcase/setup/setup.module.ts
@@ -2,6 +2,7 @@
 import {CommonModule} from '@angular/common';
 import {SetupComponent} from './setup.component';
 import {SetupRoutingModule} from './setup-routing.module';
+import {CodeHighlighterModule} from '../../components/codehighlighter/codehighlighter';

 @NgModule({
   imports: [
<|current_version|>
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {SetupComponent} from './setup.component';
import {SetupRoutingModule} from './setup-routing.module';
import {CodeHighlighterModule} from '../../components/codehighlighter/codehighlighter';

@NgModule({
  imports: [
    CommonModule,
    SetupRoutingModule
  ],
  declarations: [
    SetupComponent
  ]
})
export class SetupModule {}
<|next_version|>
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {SetupComponent} from './setup.component';
import {SetupRoutingModule} from './setup-routing.module';
import {CodeHighlighterModule} from '../../components/codehighlighter/codehighlighter';

@NgModule({
  imports: [
    CommonModule,
    CodeHighlighterModule,
    SetupRoutingModule
  ],
  declarations: [
    SetupComponent
  ]
})
export class SetupModule {}


Add id to pr model

Add id to pr model

--- app/src/models/pull-request.ts
+++ app/src/models/pull-request.ts
@@ -18,6 +18,7 @@
 }

 export class PullRequest {
+  public readonly id: number
   public readonly created: Date
   public readonly status: IAPIRefStatus
   public readonly title: string
@@ -27,6 +28,7 @@
   public readonly author: string

   public constructor(
+    id: number,
     created: Date,
     status: IAPIRefStatus,
     title: string,
@@ -35,6 +37,7 @@
     base: PullRequestRef,
     author: string
   ) {
+    this.id = id
     this.created = created
     this.status = status
     this.title = title

<|original_code|>
import { IAPIRefStatus } from '../lib/api'
import { GitHubRepository } from './github-repository'

export class PullRequestRef {
  public readonly ref: string
  public readonly sha: string
  public readonly gitHubRepository: GitHubRepository

  public constructor(
    ref: string,
    sha: string,
    gitHubRepository: GitHubRepository
  ) {
    this.ref = ref
    this.sha = sha
    this.gitHubRepository = gitHubRepository
  }
}

export class PullRequest {
  public readonly created: Date
  public readonly status: IAPIRefStatus
  public readonly title: string
  public readonly number: number
  public readonly head: PullRequestRef
  public readonly base: PullRequestRef
  public readonly author: string

  public constructor(
    created: Date,
    status: IAPIRefStatus,
    title: string,
    number_: number,
    head: PullRequestRef,
    base: PullRequestRef,
    author: string
  ) {
    this.created = created
    this.status = status
    this.title = title
    this.number = number_
    this.head = head
    this.base = base
    this.author = author
  }
}

<|edits_diff|>
--- app/src/models/pull-request.ts
+++ app/src/models/pull-request.ts
@@ -18,6 +18,7 @@
 }

 export class PullRequest {
+  public readonly id: number
   public readonly created: Date
   public readonly status: IAPIRefStatus
   public readonly title: string
@@ -27,6 +28,7 @@
   public readonly author: string

   public constructor(
+    id: number,
     created: Date,
     status: IAPIRefStatus,
     title: string,
<|current_version|>
import { IAPIRefStatus } from '../lib/api'
import { GitHubRepository } from './github-repository'

export class PullRequestRef {
  public readonly ref: string
  public readonly sha: string
  public readonly gitHubRepository: GitHubRepository

  public constructor(
    ref: string,
    sha: string,
    gitHubRepository: GitHubRepository
  ) {
    this.ref = ref
    this.sha = sha
    this.gitHubRepository = gitHubRepository
  }
}

export class PullRequest {
  public readonly id: number
  public readonly created: Date
  public readonly status: IAPIRefStatus
  public readonly title: string
  public readonly number: number
  public readonly head: PullRequestRef
  public readonly base: PullRequestRef
  public readonly author: string

  public constructor(
    id: number,
    created: Date,
    status: IAPIRefStatus,
    title: string,
    number_: number,
    head: PullRequestRef,
    base: PullRequestRef,
    author: string
  ) {
    this.created = created
    this.status = status
    this.title = title
    this.number = number_
    this.head = head
    this.base = base
    this.author = author
  }
}

<|next_version|>
import { IAPIRefStatus } from '../lib/api'
import { GitHubRepository } from './github-repository'

export class PullRequestRef {
  public readonly ref: string
  public readonly sha: string
  public readonly gitHubRepository: GitHubRepository

  public constructor(
    ref: string,
    sha: string,
    gitHubRepository: GitHubRepository
  ) {
    this.ref = ref
    this.sha = sha
    this.gitHubRepository = gitHubRepository
  }
}

export class PullRequest {
  public readonly id: number
  public readonly created: Date
  public readonly status: IAPIRefStatus
  public readonly title: string
  public readonly number: number
  public readonly head: PullRequestRef
  public readonly base: PullRequestRef
  public readonly author: string

  public constructor(
    id: number,
    created: Date,
    status: IAPIRefStatus,
    title: string,
    number_: number,
    head: PullRequestRef,
    base: PullRequestRef,
    author: string
  ) {
    this.id = id
    this.created = created
    this.status = status
    this.title = title
    this.number = number_
    this.head = head
    this.base = base
    this.author = author
  }
}


import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (
        <div {...restProps} ref={ref}>
          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >
            <div>
              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>
            </div>
          </Popover>
        </div>
      )}
    </ClickOutside>
  )
}

import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import Escapable from 'part:@sanity/components/utilities/escapable'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (
        <div {...restProps} ref={ref}>
          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >
            <div>
              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>
            </div>
          </Popover>

          {open && <Escapable onEscape={handleClose} />}
        </div>
      )}
    </ClickOutside>
  )
}

Add escape handler to menu button

[components] Add escape handler to menu button

--- packages/@sanity/components/src/menuButton/menuButton.tsx
+++ packages/@sanity/components/src/menuButton/menuButton.tsx
@@ -1,6 +1,7 @@
 import Button from 'part:@sanity/components/buttons/default'
 import {ClickOutside} from 'part:@sanity/components/click-outside'
 import {Popover} from 'part:@sanity/components/popover'
+import Escapable from 'part:@sanity/components/utilities/escapable'
 import React, {useCallback} from 'react'
 import {ButtonProps} from '../buttons'
 import {Placement} from '../types'
@@ -45,6 +46,8 @@
               </Button>
             </div>
           </Popover>
+
+          {open && <Escapable onEscape={handleClose} />}
         </div>
       )}
     </ClickOutside>

import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import Escapable from 'part:@sanity/components/utilities/escapable'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (
        <div {...restProps} ref={ref}>
          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >
            <div>
              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>
            </div>
          </Popover>
        </div>
      )}
    </ClickOutside>
  )
}

<|original_code|>
import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (

          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >

              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>

          </Popover>

      )}
    </ClickOutside>
  )
}

<|edits_diff|>
--- packages/@sanity/components/src/menuButton/menuButton.tsx
+++ packages/@sanity/components/src/menuButton/menuButton.tsx
@@ -1,6 +1,7 @@
 import Button from 'part:@sanity/components/buttons/default'
 import {ClickOutside} from 'part:@sanity/components/click-outside'
 import {Popover} from 'part:@sanity/components/popover'
+import Escapable from 'part:@sanity/components/utilities/escapable'
 import React, {useCallback} from 'react'
 import {ButtonProps} from '../buttons'
 import {Placement} from '../types'
<|current_version|>
import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import Escapable from 'part:@sanity/components/utilities/escapable'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (

          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >

              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>

          </Popover>

      )}
    </ClickOutside>
  )
}

<|next_version|>
import Button from 'part:@sanity/components/buttons/default'
import {ClickOutside} from 'part:@sanity/components/click-outside'
import {Popover} from 'part:@sanity/components/popover'
import Escapable from 'part:@sanity/components/utilities/escapable'
import React, {useCallback} from 'react'
import {ButtonProps} from '../buttons'
import {Placement} from '../types'

interface MenuButtonProps {
  boundaryElement?: HTMLElement | null
  buttonProps?: ButtonProps
  menu?: React.ReactNode
  placement?: Placement
  open?: boolean
  setOpen: (val: boolean) => void
}

export function MenuButton(props: MenuButtonProps & React.HTMLProps<HTMLDivElement>) {
  const {
    boundaryElement,
    buttonProps,
    children,
    menu,
    open,
    placement,
    setOpen,
    ...restProps
  } = props

  const handleClose = useCallback(() => setOpen(false), [setOpen])
  const handleButtonClick = useCallback(() => setOpen(!open), [open, setOpen])

  return (
    <ClickOutside onClickOutside={handleClose}>
      {ref => (

          <Popover
            boundaryElement={boundaryElement}
            content={menu}
            open={open}
            placement={placement}
          >

              <Button {...buttonProps} onClick={handleButtonClick}>
                {children}
              </Button>

          </Popover>

          {open && <Escapable onEscape={handleClose} />}

      )}
    </ClickOutside>
  )
}


Fix bug in init process migration

Fix bug in init process migration

--- src/components/cli/migrate-init.ts
+++ src/components/cli/migrate-init.ts
@@ -17,8 +17,11 @@
                 process.parentPID = newPid;
             }
         }
+        pidZero.parentPID = 0;
+        Memory.processMemory[newPid] = _.cloneDeep(Memory.processMemory[0]);
         delete (processTable[0]);
         addProcess(p);
+        p.pid = 0;
         storeProcessTable();
     }
 };

<|original_code|>
import { addProcess, storeProcessTable, processTable } from "../kernel/kernel";
import Process = require("../processes/process");
import InitProcess = require("../processes/init");
export = function (___: any) {
    let p = new InitProcess(0, 0);
    let pidZero = processTable[0];
    if (!pidZero) {
        addProcess(p);
        p.pid = 0;
        storeProcessTable();
    } else {
        addProcess(pidZero);
        let newPid = pidZero.pid;
        let processList: Process[] = _.values(processTable) as Process[];
        for (let process of processList) {
            if (process.parentPID === 0) {
                process.parentPID = newPid;
            }
        }
        delete (processTable[0]);
        addProcess(p);
        storeProcessTable();
    }
};

<|edits_diff|>
--- src/components/cli/migrate-init.ts
+++ src/components/cli/migrate-init.ts
@@ -17,6 +17,8 @@
                 process.parentPID = newPid;
             }
         }
+        pidZero.parentPID = 0;
+        Memory.processMemory[newPid] = _.cloneDeep(Memory.processMemory[0]);
         delete (processTable[0]);
         addProcess(p);
         storeProcessTable();
<|current_version|>
import { addProcess, storeProcessTable, processTable } from "../kernel/kernel";
import Process = require("../processes/process");
import InitProcess = require("../processes/init");
export = function (___: any) {
    let p = new InitProcess(0, 0);
    let pidZero = processTable[0];
    if (!pidZero) {
        addProcess(p);
        p.pid = 0;
        storeProcessTable();
    } else {
        addProcess(pidZero);
        let newPid = pidZero.pid;
        let processList: Process[] = _.values(processTable) as Process[];
        for (let process of processList) {
            if (process.parentPID === 0) {
                process.parentPID = newPid;
            }
        }
        pidZero.parentPID = 0;
        Memory.processMemory[newPid] = _.cloneDeep(Memory.processMemory[0]);
        delete (processTable[0]);
        addProcess(p);
        storeProcessTable();
    }
};

<|next_version|>
import { addProcess, storeProcessTable, processTable } from "../kernel/kernel";
import Process = require("../processes/process");
import InitProcess = require("../processes/init");
export = function (___: any) {
    let p = new InitProcess(0, 0);
    let pidZero = processTable[0];
    if (!pidZero) {
        addProcess(p);
        p.pid = 0;
        storeProcessTable();
    } else {
        addProcess(pidZero);
        let newPid = pidZero.pid;
        let processList: Process[] = _.values(processTable) as Process[];
        for (let process of processList) {
            if (process.parentPID === 0) {
                process.parentPID = newPid;
            }
        }
        pidZero.parentPID = 0;
        Memory.processMemory[newPid] = _.cloneDeep(Memory.processMemory[0]);
        delete (processTable[0]);
        addProcess(p);
        p.pid = 0;
        storeProcessTable();
    }
};


Update the message broker to publish accidents

--- app/services/MessageBroker.ts
+++ app/services/MessageBroker.ts
@@ -1,5 +1,6 @@
 import {EventEmitter, Injectable} from 'angular2/angular2';
 import {IWeatherUpdate} from '../common/interfaces/WeatherInterfaces';
+import {IAccident} from '../common/interfaces/TrafficInterfaces';

 @Injectable()
 export class MessageBroker {
@@ -7,6 +8,7 @@
 	io: SocketIOClientStatic;
 	socket: SocketIOClient.Socket;
 	weatherUpdates: EventEmitter<IWeatherUpdate>;
+	accidentUpdates: EventEmitter<IAccident>;

 	constructor() {
 		// Connect to the server
@@ -15,10 +17,16 @@

 		// Create publications
 		this.weatherUpdates = new EventEmitter<IWeatherUpdate>();
+		this.accidentUpdates = new EventEmitter<IAccident>();

 		// Set up publication updating
 		this.socket.on('weatherUpdate', (update:IWeatherUpdate) => {
 			this.weatherUpdates.next(update);
+		});
+
+		this.socket.on('accident', (accident:IAccident) => {
+			console.log(`Accident involving ${accident.vehiclesInvolved} vehicles in ${accident.state} at ${accident.time}.`);
+			this.accidentUpdates.next(accident);
 		});
 	}

<|original_code|>
import {EventEmitter, Injectable} from 'angular2/angular2';
import {IWeatherUpdate} from '../common/interfaces/WeatherInterfaces';

@Injectable()
export class MessageBroker {

	io: SocketIOClientStatic;
	socket: SocketIOClient.Socket;
	weatherUpdates: EventEmitter<IWeatherUpdate>;

	constructor() {
		// Connect to the server
		this.io = io;
		this.socket = io.connect();

		// Create publications
		this.weatherUpdates = new EventEmitter<IWeatherUpdate>();

		// Set up publication updating
		this.socket.on('weatherUpdate', (update:IWeatherUpdate) => {
			this.weatherUpdates.next(update);
		});
	}

	getWeatherUpdates() : EventEmitter<IWeatherUpdate> {
		return this.weatherUpdates;
	}
}

<|edits_diff|>
--- app/services/MessageBroker.ts
+++ app/services/MessageBroker.ts
@@ -1,5 +1,6 @@
 import {EventEmitter, Injectable} from 'angular2/angular2';
 import {IWeatherUpdate} from '../common/interfaces/WeatherInterfaces';
+import {IAccident} from '../common/interfaces/TrafficInterfaces';

 @Injectable()
 export class MessageBroker {
@@ -7,6 +8,7 @@
 	io: SocketIOClientStatic;
 	socket: SocketIOClient.Socket;
 	weatherUpdates: EventEmitter<IWeatherUpdate>;
+	accidentUpdates: EventEmitter<IAccident>;

 	constructor() {
 		// Connect to the server
@@ -15,6 +17,7 @@

 		// Create publications
 		this.weatherUpdates = new EventEmitter<IWeatherUpdate>();
+		this.accidentUpdates = new EventEmitter<IAccident>();

 		// Set up publication updating
 		this.socket.on('weatherUpdate', (update:IWeatherUpdate) => {
<|current_version|>
import {EventEmitter, Injectable} from 'angular2/angular2';
import {IWeatherUpdate} from '../common/interfaces/WeatherInterfaces';
import {IAccident} from '../common/interfaces/TrafficInterfaces';

@Injectable()
export class MessageBroker {

	io: SocketIOClientStatic;
	socket: SocketIOClient.Socket;
	weatherUpdates: EventEmitter<IWeatherUpdate>;
	accidentUpdates: EventEmitter<IAccident>;

	constructor() {
		// Connect to the server
		this.io = io;
		this.socket = io.connect();

		// Create publications
		this.weatherUpdates = new EventEmitter<IWeatherUpdate>();
		this.accidentUpdates = new EventEmitter<IAccident>();

		// Set up publication updating
		this.socket.on('weatherUpdate', (update:IWeatherUpdate) => {
			this.weatherUpdates.next(update);
		});
	}

	getWeatherUpdates() : EventEmitter<IWeatherUpdate> {
		return this.weatherUpdates;
	}
}

<|next_version|>
import {EventEmitter, Injectable} from 'angular2/angular2';
import {IWeatherUpdate} from '../common/interfaces/WeatherInterfaces';
import {IAccident} from '../common/interfaces/TrafficInterfaces';

@Injectable()
export class MessageBroker {

	io: SocketIOClientStatic;
	socket: SocketIOClient.Socket;
	weatherUpdates: EventEmitter<IWeatherUpdate>;
	accidentUpdates: EventEmitter<IAccident>;

	constructor() {
		// Connect to the server
		this.io = io;
		this.socket = io.connect();

		// Create publications
		this.weatherUpdates = new EventEmitter<IWeatherUpdate>();
		this.accidentUpdates = new EventEmitter<IAccident>();

		// Set up publication updating
		this.socket.on('weatherUpdate', (update:IWeatherUpdate) => {
			this.weatherUpdates.next(update);
		});

		this.socket.on('accident', (accident:IAccident) => {
			console.log(`Accident involving ${accident.vehiclesInvolved} vehicles in ${accident.state} at ${accident.time}.`);
			this.accidentUpdates.next(accident);
		});
	}

	getWeatherUpdates() : EventEmitter<IWeatherUpdate> {
		return this.weatherUpdates;
	}
}


Add express.static route to serve image files

--- backend/src/index.ts
+++ backend/src/index.ts
@@ -1,6 +1,7 @@
 import { GraphQLServer } from 'graphql-yoga';
 import { prisma } from './generated/prisma-client';
 import resolvers from './resolvers';
+const express = require('express');

 const server = new GraphQLServer({
   typeDefs: 'src/schema.graphql',
@@ -11,4 +12,7 @@
   }),
 });

+// The 'files' directory should be a docker volume, maybe in a dedicated container
+server.express.use('/files', express.static('files'));
+
 server.start(() => console.log('Server is running on http://localhost:4000'));

<|original_code|>
import { GraphQLServer } from 'graphql-yoga';
import { prisma } from './generated/prisma-client';
import resolvers from './resolvers';

const server = new GraphQLServer({
  typeDefs: 'src/schema.graphql',
  resolvers,
  context: req => ({
    ...req,
    db: prisma,
  }),
});

server.start(() => console.log('Server is running on http://localhost:4000'));

<|edits_diff|>
--- backend/src/index.ts
+++ backend/src/index.ts
@@ -1,6 +1,7 @@
 import { GraphQLServer } from 'graphql-yoga';
 import { prisma } from './generated/prisma-client';
 import resolvers from './resolvers';
+const express = require('express');

 const server = new GraphQLServer({
   typeDefs: 'src/schema.graphql',
<|current_version|>
import { GraphQLServer } from 'graphql-yoga';
import { prisma } from './generated/prisma-client';
import resolvers from './resolvers';
const express = require('express');

const server = new GraphQLServer({
  typeDefs: 'src/schema.graphql',
  resolvers,
  context: req => ({
    ...req,
    db: prisma,
  }),
});

server.start(() => console.log('Server is running on http://localhost:4000'));

<|next_version|>
import { GraphQLServer } from 'graphql-yoga';
import { prisma } from './generated/prisma-client';
import resolvers from './resolvers';
const express = require('express');

const server = new GraphQLServer({
  typeDefs: 'src/schema.graphql',
  resolvers,
  context: req => ({
    ...req,
    db: prisma,
  }),
});

// The 'files' directory should be a docker volume, maybe in a dedicated container
server.express.use('/files', express.static('files'));

server.start(() => console.log('Server is running on http://localhost:4000'));


Enable semantic features (such as error reporting) in JS/TS notebook cells

--- extensions/typescript-language-features/src/utils/fileSchemes.ts
+++ extensions/typescript-language-features/src/utils/fileSchemes.ts
@@ -9,11 +9,13 @@
 /** Live share scheme */
 export const vsls = 'vsls';
 export const walkThroughSnippet = 'walkThroughSnippet';
+export const vscodeNotebookCell = 'vscode-notebook-cell';

 export const semanticSupportedSchemes = [
 	file,
 	untitled,
 	walkThroughSnippet,
+	vscodeNotebookCell,
 ];

 /**

<|original_code|>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

export const file = 'file';
export const untitled = 'untitled';
export const git = 'git';
/** Live share scheme */
export const vsls = 'vsls';
export const walkThroughSnippet = 'walkThroughSnippet';

export const semanticSupportedSchemes = [
	file,
	untitled,
	walkThroughSnippet,
];

/**
 * File scheme for which JS/TS language feature should be disabled
 */
export const disabledSchemes = new Set([
	git,
	vsls
]);

<|edits_diff|>
--- extensions/typescript-language-features/src/utils/fileSchemes.ts
+++ extensions/typescript-language-features/src/utils/fileSchemes.ts
@@ -9,6 +9,7 @@
 /** Live share scheme */
 export const vsls = 'vsls';
 export const walkThroughSnippet = 'walkThroughSnippet';
+export const vscodeNotebookCell = 'vscode-notebook-cell';

 export const semanticSupportedSchemes = [
 	file,
<|current_version|>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

export const file = 'file';
export const untitled = 'untitled';
export const git = 'git';
/** Live share scheme */
export const vsls = 'vsls';
export const walkThroughSnippet = 'walkThroughSnippet';
export const vscodeNotebookCell = 'vscode-notebook-cell';

export const semanticSupportedSchemes = [
	file,
	untitled,
	walkThroughSnippet,
];

/**
 * File scheme for which JS/TS language feature should be disabled
 */
export const disabledSchemes = new Set([
	git,
	vsls
]);

<|next_version|>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

export const file = 'file';
export const untitled = 'untitled';
export const git = 'git';
/** Live share scheme */
export const vsls = 'vsls';
export const walkThroughSnippet = 'walkThroughSnippet';
export const vscodeNotebookCell = 'vscode-notebook-cell';

export const semanticSupportedSchemes = [
	file,
	untitled,
	walkThroughSnippet,
	vscodeNotebookCell,
];

/**
 * File scheme for which JS/TS language feature should be disabled
 */
export const disabledSchemes = new Set([
	git,
	vsls
]);


Add validationState to JsonFormsState type

--- packages/core/src/store.ts
+++ packages/core/src/store.ts
@@ -1,6 +1,7 @@
 import { Store } from 'redux';
 import { JsonSchema } from './models/jsonSchema';
 import { UISchemaElement } from './models/uischema';
+import { ValidationState } from './reducers/validation';

 export interface JsonFormsStore extends Store<any> {
 }
@@ -11,6 +12,7 @@
       schema?: JsonSchema;
       uischema?: UISchemaElement;
     };
+    validation?: ValidationState,
     renderers?: any[];
     fields?: any[];
     // allow additional state for JSONForms

<|original_code|>
import { Store } from 'redux';
import { JsonSchema } from './models/jsonSchema';
import { UISchemaElement } from './models/uischema';

export interface JsonFormsStore extends Store<any> {
}
export interface JsonFormsState {
  jsonforms: {
    common: {
      data: any;
      schema?: JsonSchema;
      uischema?: UISchemaElement;
    };
    renderers?: any[];
    fields?: any[];
    // allow additional state for JSONForms
    [x: string]: any;
  };
}

export interface JsonFormsInitialState {
  data: any;
  schema?: JsonSchema;
  uischema?: UISchemaElement;
  // allow additional state
  [x: string]: any;
}

<|edits_diff|>
--- packages/core/src/store.ts
+++ packages/core/src/store.ts
@@ -1,6 +1,7 @@
 import { Store } from 'redux';
 import { JsonSchema } from './models/jsonSchema';
 import { UISchemaElement } from './models/uischema';
+import { ValidationState } from './reducers/validation';

 export interface JsonFormsStore extends Store<any> {
 }
<|current_version|>
import { Store } from 'redux';
import { JsonSchema } from './models/jsonSchema';
import { UISchemaElement } from './models/uischema';
import { ValidationState } from './reducers/validation';

export interface JsonFormsStore extends Store<any> {
}
export interface JsonFormsState {
  jsonforms: {
    common: {
      data: any;
      schema?: JsonSchema;
      uischema?: UISchemaElement;
    };
    renderers?: any[];
    fields?: any[];
    // allow additional state for JSONForms
    [x: string]: any;
  };
}

export interface JsonFormsInitialState {
  data: any;
  schema?: JsonSchema;
  uischema?: UISchemaElement;
  // allow additional state
  [x: string]: any;
}

<|next_version|>
import { Store } from 'redux';
import { JsonSchema } from './models/jsonSchema';
import { UISchemaElement } from './models/uischema';
import { ValidationState } from './reducers/validation';

export interface JsonFormsStore extends Store<any> {
}
export interface JsonFormsState {
  jsonforms: {
    common: {
      data: any;
      schema?: JsonSchema;
      uischema?: UISchemaElement;
    };
    validation?: ValidationState,
    renderers?: any[];
    fields?: any[];
    // allow additional state for JSONForms
    [x: string]: any;
  };
}

export interface JsonFormsInitialState {
  data: any;
  schema?: JsonSchema;
  uischema?: UISchemaElement;
  // allow additional state
  [x: string]: any;
}


Add missing TranslateModule in BandModule

--- client/imports/band/band.module.ts
+++ client/imports/band/band.module.ts
@@ -2,6 +2,7 @@
 import { CommonModule }   from '@angular/common';
 import { MaterialModule } from '@angular/material';
 import { FlexLayoutModule } from '@angular/flex-layout';
+import { TranslateModule } from '@ngx-translate/core';

 import { SongModule } from '../song/song.module';

@@ -14,6 +15,7 @@
     CommonModule,
     MaterialModule,
     FlexLayoutModule,
+    TranslateModule,
     SongModule,
     BandRoutingModule
   ],

<|original_code|>
import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';
import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';

import { SongModule } from '../song/song.module';

import { BandComponent } from './band.component';

import { BandRoutingModule } from './band-routing.module';

@NgModule({
  imports: [
    CommonModule,
    MaterialModule,
    FlexLayoutModule,
    SongModule,
    BandRoutingModule
  ],
  declarations: [
    BandComponent
  ]
})

export class BandModule {}

<|edits_diff|>
--- client/imports/band/band.module.ts
+++ client/imports/band/band.module.ts
@@ -2,6 +2,7 @@
 import { CommonModule }   from '@angular/common';
 import { MaterialModule } from '@angular/material';
 import { FlexLayoutModule } from '@angular/flex-layout';
+import { TranslateModule } from '@ngx-translate/core';

 import { SongModule } from '../song/song.module';

<|current_version|>
import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';
import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';
import { TranslateModule } from '@ngx-translate/core';

import { SongModule } from '../song/song.module';

import { BandComponent } from './band.component';

import { BandRoutingModule } from './band-routing.module';

@NgModule({
  imports: [
    CommonModule,
    MaterialModule,
    FlexLayoutModule,
    SongModule,
    BandRoutingModule
  ],
  declarations: [
    BandComponent
  ]
})

export class BandModule {}

<|next_version|>
import { NgModule }       from '@angular/core';
import { CommonModule }   from '@angular/common';
import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';
import { TranslateModule } from '@ngx-translate/core';

import { SongModule } from '../song/song.module';

import { BandComponent } from './band.component';

import { BandRoutingModule } from './band-routing.module';

@NgModule({
  imports: [
    CommonModule,
    MaterialModule,
    FlexLayoutModule,
    TranslateModule,
    SongModule,
    BandRoutingModule
  ],
  declarations: [
    BandComponent
  ]
})

export class BandModule {}


Set ** path to NotFoundPage

Set ** path to NotFoundPage

--- frontend/src/app/app-routing.module.ts
+++ frontend/src/app/app-routing.module.ts
@@ -4,6 +4,7 @@
 import { BuildsPage } from '@page/builds/builds.page';
 import { ChampionPage } from '@page/champion/champion.page';
 import { ChampionsPage } from '@page/champions/champions.page';
+import { NotFoundPage } from '@page/error/not-found.page';

 const routes: Routes = [
   { path: 'builds', redirectTo: '/champions', pathMatch: 'full' },
@@ -11,6 +12,7 @@
   { path: 'champions', component: ChampionsPage },
   { path: 'champions/:name', component: ChampionPage },
   { path: '', redirectTo: '/champions', pathMatch: 'full' },
+  { path: '**', component: NotFoundPage }
 ];

 @NgModule({

<|original_code|>
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { BuildsPage } from '@page/builds/builds.page';
import { ChampionPage } from '@page/champion/champion.page';
import { ChampionsPage } from '@page/champions/champions.page';

const routes: Routes = [
  { path: 'builds', redirectTo: '/champions', pathMatch: 'full' },
  { path: 'builds/:buildId', component: BuildsPage },
  { path: 'champions', component: ChampionsPage },
  { path: 'champions/:name', component: ChampionPage },
  { path: '', redirectTo: '/champions', pathMatch: 'full' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

<|edits_diff|>
--- frontend/src/app/app-routing.module.ts
+++ frontend/src/app/app-routing.module.ts
@@ -4,6 +4,7 @@
 import { BuildsPage } from '@page/builds/builds.page';
 import { ChampionPage } from '@page/champion/champion.page';
 import { ChampionsPage } from '@page/champions/champions.page';
+import { NotFoundPage } from '@page/error/not-found.page';

 const routes: Routes = [
   { path: 'builds', redirectTo: '/champions', pathMatch: 'full' },
<|current_version|>
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { BuildsPage } from '@page/builds/builds.page';
import { ChampionPage } from '@page/champion/champion.page';
import { ChampionsPage } from '@page/champions/champions.page';
import { NotFoundPage } from '@page/error/not-found.page';

const routes: Routes = [
  { path: 'builds', redirectTo: '/champions', pathMatch: 'full' },
  { path: 'builds/:buildId', component: BuildsPage },
  { path: 'champions', component: ChampionsPage },
  { path: 'champions/:name', component: ChampionPage },
  { path: '', redirectTo: '/champions', pathMatch: 'full' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

<|next_version|>
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { BuildsPage } from '@page/builds/builds.page';
import { ChampionPage } from '@page/champion/champion.page';
import { ChampionsPage } from '@page/champions/champions.page';
import { NotFoundPage } from '@page/error/not-found.page';

const routes: Routes = [
  { path: 'builds', redirectTo: '/champions', pathMatch: 'full' },
  { path: 'builds/:buildId', component: BuildsPage },
  { path: 'champions', component: ChampionsPage },
  { path: 'champions/:name', component: ChampionPage },
  { path: '', redirectTo: '/champions', pathMatch: 'full' },
  { path: '**', component: NotFoundPage }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}


Allow to update limits and credentials for VMware service settings [WAL-2796]

--- src/vmware/provider.ts
+++ src/vmware/provider.ts
@@ -4,8 +4,14 @@
 import { VMwareForm } from './VMwareForm';

 const serializer = pick([
+  'backend_url',
   'username',
   'password',
+  'default_cluster_label',
+  'max_cpu',
+  'max_ram',
+  'max_disk',
+  'max_disk_total',
 ]);

 ProvidersRegistry.register({

<|original_code|>
import { pick } from '@waldur/core/utils';
import * as ProvidersRegistry from '@waldur/providers/registry';

import { VMwareForm } from './VMwareForm';

const serializer = pick([
  'username',
  'password',
]);

ProvidersRegistry.register({
  name: 'VMware',
  type: 'VMware',
  icon: 'icon-vmware.png',
  endpoint: 'vmware',
  component: VMwareForm,
  serializer,
});

<|edits_diff|>
--- src/vmware/provider.ts
+++ src/vmware/provider.ts
@@ -4,6 +4,7 @@
 import { VMwareForm } from './VMwareForm';

 const serializer = pick([
+  'backend_url',
   'username',
   'password',
 ]);
<|current_version|>
import { pick } from '@waldur/core/utils';
import * as ProvidersRegistry from '@waldur/providers/registry';

import { VMwareForm } from './VMwareForm';

const serializer = pick([
  'backend_url',
  'username',
  'password',
]);

ProvidersRegistry.register({
  name: 'VMware',
  type: 'VMware',
  icon: 'icon-vmware.png',
  endpoint: 'vmware',
  component: VMwareForm,
  serializer,
});

<|next_version|>
import { pick } from '@waldur/core/utils';
import * as ProvidersRegistry from '@waldur/providers/registry';

import { VMwareForm } from './VMwareForm';

const serializer = pick([
  'backend_url',
  'username',
  'password',
  'default_cluster_label',
  'max_cpu',
  'max_ram',
  'max_disk',
  'max_disk_total',
]);

ProvidersRegistry.register({
  name: 'VMware',
  type: 'VMware',
  icon: 'icon-vmware.png',
  endpoint: 'vmware',
  component: VMwareForm,
  serializer,
});


Add additional exports to module entry point

Added a few additional exports to the module's index to support use with
react-docgen-typescript-loader. This allows this package to more easily
be used as a peer dependency.

--- src/index.ts
+++ src/index.ts
@@ -1,18 +1,24 @@
 import {
   ComponentDoc,
+  FileParser,
   parse,
+  ParserOptions,
   PropItem,
   PropItemType,
   Props,
+  withCompilerOptions,
   withCustomConfig,
   withDefaultConfig
 } from './parser';

 export {
   parse,
+  withCompilerOptions,
   withDefaultConfig,
   withCustomConfig,
   ComponentDoc,
+  FileParser,
+  ParserOptions,
   Props,
   PropItem,
   PropItemType

<|original_code|>
import {
  ComponentDoc,
  parse,
  PropItem,
  PropItemType,
  Props,
  withCustomConfig,
  withDefaultConfig
} from './parser';

export {
  parse,
  withDefaultConfig,
  withCustomConfig,
  ComponentDoc,
  Props,
  PropItem,
  PropItemType
};

<|edits_diff|>
--- src/index.ts
+++ src/index.ts
@@ -1,15 +1,19 @@
 import {
   ComponentDoc,
+  FileParser,
   parse,
+  ParserOptions,
   PropItem,
   PropItemType,
   Props,
+  withCompilerOptions,
   withCustomConfig,
   withDefaultConfig
 } from './parser';

 export {
   parse,
+  withCompilerOptions,
   withDefaultConfig,
   withCustomConfig,
   ComponentDoc,
<|current_version|>
import {
  ComponentDoc,
  FileParser,
  parse,
  ParserOptions,
  PropItem,
  PropItemType,
  Props,
  withCompilerOptions,
  withCustomConfig,
  withDefaultConfig
} from './parser';

export {
  parse,
  withCompilerOptions,
  withDefaultConfig,
  withCustomConfig,
  ComponentDoc,
  Props,
  PropItem,
  PropItemType
};

<|next_version|>
import {
  ComponentDoc,
  FileParser,
  parse,
  ParserOptions,
  PropItem,
  PropItemType,
  Props,
  withCompilerOptions,
  withCustomConfig,
  withDefaultConfig
} from './parser';

export {
  parse,
  withCompilerOptions,
  withDefaultConfig,
  withCustomConfig,
  ComponentDoc,
  FileParser,
  ParserOptions,
  Props,
  PropItem,
  PropItemType
};


Disable some auto collected metrics

Disable some auto collected metrics

--- src/telemetry.ts
+++ src/telemetry.ts
@@ -5,7 +5,10 @@
 import * as appInsights from "applicationinsights";

 appInsights.setup(Constants.AiKey)
+    .setAutoCollectDependencies(false)
     .setAutoCollectPerformance(false)
+    .setAutoCollectRequests(false)
+    .setAutoDependencyCorrelation(false)
     .start();

 export class Telemetry {

<|original_code|>
'use strict';

import { RestClientSettings } from './models/configurationSettings';
import * as Constants from './constants';
import * as appInsights from "applicationinsights";

appInsights.setup(Constants.AiKey)
    .setAutoCollectPerformance(false)
    .start();

export class Telemetry {
    private static readonly restClientSettings: RestClientSettings = new RestClientSettings();

    public static sendEvent(eventName: string, properties?: { [key: string]: string }) {
        try {
            if (Telemetry.restClientSettings.enableTelemetry) {
                appInsights.defaultClient.trackEvent({name: eventName, properties});
            }
        } catch {
        }
    }
}
<|edits_diff|>
--- src/telemetry.ts
+++ src/telemetry.ts
@@ -5,6 +5,7 @@
 import * as appInsights from "applicationinsights";

 appInsights.setup(Constants.AiKey)
+    .setAutoCollectDependencies(false)
     .setAutoCollectPerformance(false)
     .start();

<|current_version|>
'use strict';

import { RestClientSettings } from './models/configurationSettings';
import * as Constants from './constants';
import * as appInsights from "applicationinsights";

appInsights.setup(Constants.AiKey)
    .setAutoCollectDependencies(false)
    .setAutoCollectPerformance(false)
    .start();

export class Telemetry {
    private static readonly restClientSettings: RestClientSettings = new RestClientSettings();

    public static sendEvent(eventName: string, properties?: { [key: string]: string }) {
        try {
            if (Telemetry.restClientSettings.enableTelemetry) {
                appInsights.defaultClient.trackEvent({name: eventName, properties});
            }
        } catch {
        }
    }
}
<|next_version|>
'use strict';

import { RestClientSettings } from './models/configurationSettings';
import * as Constants from './constants';
import * as appInsights from "applicationinsights";

appInsights.setup(Constants.AiKey)
    .setAutoCollectDependencies(false)
    .setAutoCollectPerformance(false)
    .setAutoCollectRequests(false)
    .setAutoDependencyCorrelation(false)
    .start();

export class Telemetry {
    private static readonly restClientSettings: RestClientSettings = new RestClientSettings();

    public static sendEvent(eventName: string, properties?: { [key: string]: string }) {
        try {
            if (Telemetry.restClientSettings.enableTelemetry) {
                appInsights.defaultClient.trackEvent({name: eventName, properties});
            }
        } catch {
        }
    }
}


Clear screenshot CDN cache after reuploading

--- packages/skin-database/tasks/screenshotSkin.ts
+++ packages/skin-database/tasks/screenshotSkin.ts
@@ -5,6 +5,7 @@
 import md5Buffer from "md5";
 import * as S3 from "../s3";
 import * as Skins from "../data/skins";
+import * as CloudFlare from "../CloudFlare";

 const Shooter = require("../shooter");
 const temp = _temp.track();
@@ -36,6 +37,7 @@
   if (success) {
     console.log("Completed screenshot");
     await S3.putScreenshot(md5, fs.readFileSync(tempScreenshotPath));
+    await CloudFlare.purgeFiles([Skins.getScreenshotUrl(actualMd5)]);
   } else {
     console.log(`Screenshot failed ${md5}`);
   }

<|original_code|>
// eslint-disable-next-line
import _temp from "temp";
import fs from "fs";
import fetch from "node-fetch";
import md5Buffer from "md5";
import * as S3 from "../s3";
import * as Skins from "../data/skins";

const Shooter = require("../shooter");
const temp = _temp.track();

export async function screenshot(md5: string, shooter: typeof Shooter) {
  const url = Skins.getSkinUrl(md5);
  const response = await fetch(url);
  if (!response.ok) {
    await Skins.recordScreenshotUpdate(md5, `Failed to download from ${url}.`);
    console.error(`Failed to download skin from "${url}".`);
    return;
  }
  const buffer = await response.buffer();
  const actualMd5 = md5Buffer(buffer);
  if (md5 !== actualMd5) {
    throw new Error("Downloaded skin had a different md5.");
  }

  const tempFile = temp.path({ suffix: ".wsz" });
  const tempScreenshotPath = temp.path({ suffix: ".png" });

  fs.writeFileSync(tempFile, buffer);

  console.log("Starting screenshot");
  const success = await shooter.takeScreenshot(tempFile, tempScreenshotPath, {
    minify: true,
    md5,
  });
  if (success) {
    console.log("Completed screenshot");
    await S3.putScreenshot(md5, fs.readFileSync(tempScreenshotPath));
  } else {
    console.log(`Screenshot failed ${md5}`);
  }
}

<|edits_diff|>
--- packages/skin-database/tasks/screenshotSkin.ts
+++ packages/skin-database/tasks/screenshotSkin.ts
@@ -5,6 +5,7 @@
 import md5Buffer from "md5";
 import * as S3 from "../s3";
 import * as Skins from "../data/skins";
+import * as CloudFlare from "../CloudFlare";

 const Shooter = require("../shooter");
 const temp = _temp.track();
<|current_version|>
// eslint-disable-next-line
import _temp from "temp";
import fs from "fs";
import fetch from "node-fetch";
import md5Buffer from "md5";
import * as S3 from "../s3";
import * as Skins from "../data/skins";
import * as CloudFlare from "../CloudFlare";

const Shooter = require("../shooter");
const temp = _temp.track();

export async function screenshot(md5: string, shooter: typeof Shooter) {
  const url = Skins.getSkinUrl(md5);
  const response = await fetch(url);
  if (!response.ok) {
    await Skins.recordScreenshotUpdate(md5, `Failed to download from ${url}.`);
    console.error(`Failed to download skin from "${url}".`);
    return;
  }
  const buffer = await response.buffer();
  const actualMd5 = md5Buffer(buffer);
  if (md5 !== actualMd5) {
    throw new Error("Downloaded skin had a different md5.");
  }

  const tempFile = temp.path({ suffix: ".wsz" });
  const tempScreenshotPath = temp.path({ suffix: ".png" });

  fs.writeFileSync(tempFile, buffer);

  console.log("Starting screenshot");
  const success = await shooter.takeScreenshot(tempFile, tempScreenshotPath, {
    minify: true,
    md5,
  });
  if (success) {
    console.log("Completed screenshot");
    await S3.putScreenshot(md5, fs.readFileSync(tempScreenshotPath));
  } else {
    console.log(`Screenshot failed ${md5}`);
  }
}

<|next_version|>
// eslint-disable-next-line
import _temp from "temp";
import fs from "fs";
import fetch from "node-fetch";
import md5Buffer from "md5";
import * as S3 from "../s3";
import * as Skins from "../data/skins";
import * as CloudFlare from "../CloudFlare";

const Shooter = require("../shooter");
const temp = _temp.track();

export async function screenshot(md5: string, shooter: typeof Shooter) {
  const url = Skins.getSkinUrl(md5);
  const response = await fetch(url);
  if (!response.ok) {
    await Skins.recordScreenshotUpdate(md5, `Failed to download from ${url}.`);
    console.error(`Failed to download skin from "${url}".`);
    return;
  }
  const buffer = await response.buffer();
  const actualMd5 = md5Buffer(buffer);
  if (md5 !== actualMd5) {
    throw new Error("Downloaded skin had a different md5.");
  }

  const tempFile = temp.path({ suffix: ".wsz" });
  const tempScreenshotPath = temp.path({ suffix: ".png" });

  fs.writeFileSync(tempFile, buffer);

  console.log("Starting screenshot");
  const success = await shooter.takeScreenshot(tempFile, tempScreenshotPath, {
    minify: true,
    md5,
  });
  if (success) {
    console.log("Completed screenshot");
    await S3.putScreenshot(md5, fs.readFileSync(tempScreenshotPath));
    await CloudFlare.purgeFiles([Skins.getScreenshotUrl(actualMd5)]);
  } else {
    console.log(`Screenshot failed ${md5}`);
  }
}


Make generator available from MutationContext through a getter.

--- src/mutators/Mutator.ts
+++ src/mutators/Mutator.ts
@@ -1,4 +1,5 @@
 import * as ts from 'typescript';
+import { Generator } from '../generator';
 import { MutationContext } from '../context';

 export abstract class Mutator {
@@ -34,4 +35,8 @@
     return [this.kind];
   }

+  get generator(): Generator {
+    return this.context.generator;
+  }
+
 }

<|original_code|>
import * as ts from 'typescript';
import { MutationContext } from '../context';

export abstract class Mutator {

  protected abstract kind: ts.SyntaxKind | ts.SyntaxKind[];

  protected abstract mutate(node: ts.Node, context?: MutationContext): ts.Node;

  protected context: MutationContext;

  public mutateNode(node: ts.Node, context: MutationContext): ts.Node {
    this.context = context;

    if (this.getKind().indexOf(node.kind) === -1) {
      return node;
    }

    if (context.wasVisited(node)) {
      return node;
    }

    const substitution = this.mutate(node, context);
    context.addVisited(substitution);

    return substitution;
  }

  public getKind(): ts.SyntaxKind[] {
    if (Array.isArray(this.kind)) {
      return this.kind;
    }

    return [this.kind];
  }

}

<|edits_diff|>
--- src/mutators/Mutator.ts
+++ src/mutators/Mutator.ts
@@ -1,4 +1,5 @@
 import * as ts from 'typescript';
+import { Generator } from '../generator';
 import { MutationContext } from '../context';

 export abstract class Mutator {
<|current_version|>
import * as ts from 'typescript';
import { Generator } from '../generator';
import { MutationContext } from '../context';

export abstract class Mutator {

  protected abstract kind: ts.SyntaxKind | ts.SyntaxKind[];

  protected abstract mutate(node: ts.Node, context?: MutationContext): ts.Node;

  protected context: MutationContext;

  public mutateNode(node: ts.Node, context: MutationContext): ts.Node {
    this.context = context;

    if (this.getKind().indexOf(node.kind) === -1) {
      return node;
    }

    if (context.wasVisited(node)) {
      return node;
    }

    const substitution = this.mutate(node, context);
    context.addVisited(substitution);

    return substitution;
  }

  public getKind(): ts.SyntaxKind[] {
    if (Array.isArray(this.kind)) {
      return this.kind;
    }

    return [this.kind];
  }

}

<|next_version|>
import * as ts from 'typescript';
import { Generator } from '../generator';
import { MutationContext } from '../context';

export abstract class Mutator {

  protected abstract kind: ts.SyntaxKind | ts.SyntaxKind[];

  protected abstract mutate(node: ts.Node, context?: MutationContext): ts.Node;

  protected context: MutationContext;

  public mutateNode(node: ts.Node, context: MutationContext): ts.Node {
    this.context = context;

    if (this.getKind().indexOf(node.kind) === -1) {
      return node;
    }

    if (context.wasVisited(node)) {
      return node;
    }

    const substitution = this.mutate(node, context);
    context.addVisited(substitution);

    return substitution;
  }

  public getKind(): ts.SyntaxKind[] {
    if (Array.isArray(this.kind)) {
      return this.kind;
    }

    return [this.kind];
  }

  get generator(): Generator {
    return this.context.generator;
  }

}


Add page level service injector

Add page level service injector

--- app/src/app/pages/project/project-page.component.ts
+++ app/src/app/pages/project/project-page.component.ts
@@ -1,7 +1,10 @@
 import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';

+import { LocalesService } from './../../locales/services/locales.service';
+
 @Component({
+    providers: [LocalesService],
     selector: 'project-page',
     templateUrl: 'project-page.component.html'
 })

<|original_code|>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
    selector: 'project-page',
    templateUrl: 'project-page.component.html'
})
export class ProjectPage implements OnInit {
    ngOnInit() {

    }
}
<|edits_diff|>
--- app/src/app/pages/project/project-page.component.ts
+++ app/src/app/pages/project/project-page.component.ts
@@ -1,5 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
+
+import { LocalesService } from './../../locales/services/locales.service';

 @Component({
     selector: 'project-page',
<|current_version|>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { LocalesService } from './../../locales/services/locales.service';

@Component({
    selector: 'project-page',
    templateUrl: 'project-page.component.html'
})
export class ProjectPage implements OnInit {
    ngOnInit() {

    }
}
<|next_version|>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { LocalesService } from './../../locales/services/locales.service';

@Component({
    providers: [LocalesService],
    selector: 'project-page',
    templateUrl: 'project-page.component.html'
})
export class ProjectPage implements OnInit {
    ngOnInit() {

    }
}