[WIP] migrate from tslint to eslint

Create-react-app does not support installing eslint.  We could turn off
PREFLIGHT_CHECK, but that could hide other issues.  Until this issue (https://github.com/facebook/create-react-app/issues/5247) is addressed, will stick with tslint for now
Esse commit está contido em:
Vott
2020-06-01 16:01:03 -07:00
commit 8679088ae9
34 arquivos alterados com 9794 adições e 4850 exclusões
+66
Ver Arquivo
@@ -0,0 +1,66 @@
/*
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
https://github.com/typescript-eslint/tslint-to-eslint-config
It represents the closest reasonable ESLint configuration to this
project's original TSLint configuration.
We recommend eventually switching this configuration to extend from
the recommended rulesets in typescript-eslint.
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
Happy linting! 💖
*/
module.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: [
// order matters
"eslint:recommended",
"prettier",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:react/recommended",
"prettier/@typescript-eslint",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json",
sourceType: "module",
},
plugins: ["@typescript-eslint", "react"],
rules: {
// order does not matter
"@typescript-eslint/await-thenable": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-implied-eval": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unnecessary-type-assertion": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/prefer-regexp-exec": "off",
"@typescript-eslint/require-await": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/unbound-method": "off",
"no-async-promise-executor": "off",
"no-case-declarations": "off",
"no-useless-escape": "off",
"prefer-const": "off",
"prefer-spread": "off",
"react/no-find-dom-node": "off",
"react/prop-types": "off",
},
};
+9512 -4702
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+13 -4
Ver Arquivo
@@ -76,8 +76,9 @@
"release-web": "npm run build && npm run webpack:prod",
"release-ci": "bash ./scripts/build.sh",
"release": "npm run build && npm run webpack:prod && electron-builder",
"pretest": "./node_modules/.bin/tslint 'src/**/*.ts*'",
"lintfix": "./node_modules/.bin/tslint 'src/**/*.ts*' --fix",
"pretest": "npm run lint",
"lint": "npx eslint 'src/**/*.ts*'",
"lint:fix": "npm run lint -- --fix",
"test": "react-scripts test --env=jsdom --silent",
"test:ci": "cross-env CI=true npm run test",
"test:coverage": "npm run test -- --coverage",
@@ -111,22 +112,30 @@
"@types/reactstrap": "^6.4.3",
"@types/redux-logger": "^3.0.6",
"@types/redux-mock-store": "^1.0.0",
"@typescript-eslint/eslint-plugin": "^3.1.0",
"@typescript-eslint/parser": "^3.1.0",
"cross-env": "^5.2.0",
"electron": "^3.0.13",
"electron-builder": "^22.6.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"eslint": "^7.1.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jsdoc": "^26.0.1",
"eslint-plugin-prefer-arrow": "^1.2.1",
"eslint-plugin-react": "^7.20.0",
"foreman": "^3.0.1",
"jest-enzyme": "^7.0.1",
"jquery": "^3.3.1",
"node-sass": "^4.10.0",
"popper.js": "^1.14.6",
"prettier": "^2.0.5",
"redux-immutable-state-invariant": "^2.1.0",
"redux-logger": "^3.0.6",
"redux-mock-store": "^1.5.3",
"ts-loader": "^5.3.0",
"tslint": "^5.11.0",
"typescript": "^3.1.6",
"typescript": "^3.9.3",
"webpack": "^4.19.1",
"webpack-cli": "^3.1.2",
"webpack-merge": "^4.1.5"
+1 -1
Ver Arquivo
@@ -5,7 +5,7 @@ import Guard from "./guard";
* Generates a random base64 encoded key to be used for encryption
* @param keySize The key size to use, defaults to 32bit
*/
export function generateKey(keySize: number = 32): string {
export function generateKey(keySize = 32): string {
return lib.WordArray.random(keySize).toString(enc.Base64);
}
+2 -2
Ver Arquivo
@@ -9,7 +9,7 @@ import Guard from "../guard";
export async function forEachAsync<T>(
this: T[],
action: (item: T) => Promise<void>,
batchSize: number = 5): Promise<void> {
batchSize = 5): Promise<void> {
Guard.null(this);
Guard.null(action);
Guard.expression(batchSize, (value) => value > 0);
@@ -37,7 +37,7 @@ export async function forEachAsync<T>(
export async function mapAsync<T, R>(
this: T[],
action: (item: T) => Promise<R>,
batchSize: number = 5): Promise<R[]> {
batchSize = 5): Promise<R[]> {
Guard.null(this);
Guard.null(action);
Guard.expression(batchSize, (value) => value > 0);
+1 -1
Ver Arquivo
@@ -9,7 +9,7 @@ describe("Map Extensions", () => {
beforeAll(registerMixins);
describe("forEachAsync", () => {
const map = testArray.map((asset) => [asset.id, asset]) as Array<[string, IAsset]>;
const map = testArray.map((asset) => [asset.id, asset]);
const testMap = new Map<string, IAsset>(map);
const output = [];
+1 -1
Ver Arquivo
@@ -9,7 +9,7 @@ import Guard from "../guard";
export async function forEachAsync<K, V>(
this: Map<K, V>,
action: (value: V, key: K) => Promise<void>,
batchSize: number = 5): Promise<void> {
batchSize = 5): Promise<void> {
Guard.null(this);
Guard.null(action);
Guard.expression(batchSize, (value) => value > 0);
+2 -2
Ver Arquivo
@@ -149,7 +149,7 @@ export default class HtmlFileReader {
private static readVideoAttributes(url: string): Promise<{ width: number, height: number, duration: number }> {
return new Promise((resolve, reject) => {
const video = document.createElement("video") as HTMLVideoElement;
const video = document.createElement("video");
video.onloadedmetadata = () => {
resolve({
width: video.videoWidth,
@@ -164,7 +164,7 @@ export default class HtmlFileReader {
private static readImageAttributes(url: string): Promise<{ width: number, height: number }> {
return new Promise((resolve, reject) => {
const image = document.createElement("img") as HTMLImageElement;
const image = document.createElement("img");
image.onload = () => {
resolve({
width: image.naturalWidth,
+1 -1
Ver Arquivo
@@ -49,5 +49,5 @@ export class IpcRendererProxy {
return deferred.promise;
}
private static ipcRenderer;
private static initialized: boolean = false;
private static initialized = false;
}
+26 -26
Ver Arquivo
@@ -46,8 +46,8 @@ export default class MockFactory {
*/
public static createAppError(
errorCode: ErrorCode = ErrorCode.Unknown,
title: string = "",
message: string = ""): IAppError {
title = "",
message = ""): IAppError {
return {
errorCode,
title,
@@ -63,11 +63,11 @@ export default class MockFactory {
* @param assetType Type of asset
*/
public static createTestAsset(
name: string = "test",
name = "test",
assetState: AssetState = AssetState.NotVisited,
path: string = encodeFileURI(`C:\\Desktop\\asset${name}.jpg`),
assetType: AssetType = AssetType.Image,
timestamp: number = 0): IAsset {
timestamp = 0): IAsset {
let testAsset = null;
switch (assetType) {
case AssetType.Video:
@@ -208,7 +208,7 @@ export default class MockFactory {
* @param rootAsset The parent video asset
* @param count The number of child assets to create (default 10)
*/
public static createChildVideoAssets(rootAsset: IAsset, count: number = 10): IAsset[] {
public static createChildVideoAssets(rootAsset: IAsset, count = 10): IAsset[] {
return [...Array(count).keys()].map((index) => {
return this.createChildVideoAsset(rootAsset, index);
});
@@ -219,7 +219,7 @@ export default class MockFactory {
* @param count Number of assets to create (default: 10)
* @param startIndex The index that the assets should start at (default: 1)
*/
public static createTestAssets(count: number = 10, startIndex: number = 1): IAsset[] {
public static createTestAssets(count = 10, startIndex = 1): IAsset[] {
const assets: IAsset[] = [];
for (let i = startIndex; i < (count + startIndex); i++) {
assets.push(MockFactory.createTestAsset(i.toString()));
@@ -256,7 +256,7 @@ export default class MockFactory {
* Creates array of fake IProject
* @param count Number of projects
*/
public static createTestProjects(count: number = 10): IProject[] {
public static createTestProjects(count = 10): IProject[] {
const projects: IProject[] = [];
for (let i = 1; i <= count; i++) {
projects.push(MockFactory.createTestProject(i.toString()));
@@ -270,7 +270,7 @@ export default class MockFactory {
* @param name Name of project. project.id = `project-${name}` and project.name = `Project ${name}`
* @param tagCount number of tags to create for project
*/
public static createTestProject(name: string = "test", tagCount: number = 5): IProject {
public static createTestProject(name = "test", tagCount = 5): IProject {
const connection = MockFactory.createTestConnection(name);
return {
@@ -299,7 +299,7 @@ export default class MockFactory {
* Creates fake IV1Project
* @param name Name of project.
*/
public static createTestV1Project(frameCount: number = 10): IV1Project {
public static createTestV1Project(frameCount = 10): IV1Project {
const frames: { [frameName: string]: IV1Region[]; } = {};
for (let i = 0; i < frameCount; i++) {
const name = `testFrame${i}.jpg`;
@@ -321,7 +321,7 @@ export default class MockFactory {
* Creates fake IV1Project
* @param name Name of project.
*/
public static createTestV1VideoProject(frameCount: number = 10): IV1Project {
public static createTestV1VideoProject(frameCount = 10): IV1Project {
const frames: { [frameName: string]: IV1Region[]; } = {};
for (let i = 0; i < frameCount; i++) {
const name = `${i + 1}`;
@@ -342,7 +342,7 @@ export default class MockFactory {
/**
* Creates fake IV1Region
*/
public static createTestV1Regions(count: number = 3): IV1Region[] {
public static createTestV1Regions(count = 3): IV1Region[] {
const regions: IV1Region[] = [];
const left = randomIntInRange(0, 511);
const top = randomIntInRange(0, 383);
@@ -414,7 +414,7 @@ export default class MockFactory {
* Creates fake Azure containers
* @param count Number of containers
*/
public static createAzureContainers(count: number = 3) {
public static createAzureContainers(count = 3) {
const result = [];
for (let i = 0; i < count; i++) {
result.push({
@@ -458,7 +458,7 @@ export default class MockFactory {
* @param id ID of blob
* @param count Number of blobs
*/
public static createAzureBlobs(id: number = 1, count: number = 10) {
public static createAzureBlobs(id = 1, count = 10) {
const result = [];
for (let i = 0; i < count; i++) {
result.push({
@@ -472,7 +472,7 @@ export default class MockFactory {
* Create array of fake ITag
* @param count Number of tags
*/
public static createTestTags(count: number = 5): ITag[] {
public static createTestTags(count = 5): ITag[] {
const tags: ITag[] = [];
for (let i = 0; i < count; i++) {
tags.push(MockFactory.createTestTag(i.toString()));
@@ -484,7 +484,7 @@ export default class MockFactory {
* Create fake ITag with random color
* @param name Name of tag
*/
public static createTestTag(name: string = "1"): ITag {
public static createTestTag(name = "1"): ITag {
return {
name: `Tag ${name}`,
color: MockFactory.randomColor(),
@@ -495,7 +495,7 @@ export default class MockFactory {
* Create array of IConnection, half Azure Blob connections, half Local File Storage connections
* @param count Number of connections
*/
public static createTestConnections(count: number = 10): IConnection[] {
public static createTestConnections(count = 10): IConnection[] {
const connections: IConnection[] = [];
for (let i = 1; i <= (count / 2); i++) {
connections.push(MockFactory.createTestCloudConnection(i.toString()));
@@ -510,7 +510,7 @@ export default class MockFactory {
*
* @param name Name of connection
*/
public static createTestCloudConnection(name: string = "test"): IConnection {
public static createTestCloudConnection(name = "test"): IConnection {
return MockFactory.createTestConnection(name, "azureBlobStorage");
}
@@ -518,7 +518,7 @@ export default class MockFactory {
* Create array of IConnection of type Bing Image Search
* @param count Number of connections
*/
public static createTestBingConnections(count: number = 10): IConnection[] {
public static createTestBingConnections(count = 10): IConnection[] {
const connections: IConnection[] = [];
for (let i = 1; i <= count; i++) {
connections.push(MockFactory.createTestConnection(i.toString(), "bingImageSearch"));
@@ -532,7 +532,7 @@ export default class MockFactory {
* @param providerType Type of Connection - default local file system
*/
public static createTestConnection(
name: string = "test", providerType: string = "localFileSystemProxy"): IConnection {
name = "test", providerType = "localFileSystemProxy"): IConnection {
return {
id: `connection-${name}`,
name: `Connection ${name}`,
@@ -653,7 +653,7 @@ export default class MockFactory {
* Create array of IStorageProviderRegistrationOptions
* @param count Number of storage provider registrations to create
*/
public static createStorageProviderRegistrations(count: number = 10): IStorageProviderRegistrationOptions[] {
public static createStorageProviderRegistrations(count = 10): IStorageProviderRegistrationOptions[] {
const registrations: IStorageProviderRegistrationOptions[] = [];
for (let i = 1; i <= count; i++) {
registrations.push(MockFactory.createStorageProviderRegistration(i.toString()));
@@ -666,7 +666,7 @@ export default class MockFactory {
* Create array of IAssetProviderRegistrationOptions
* @param count Number of Asset Provider Registrations to create
*/
public static createAssetProviderRegistrations(count: number = 10): IAssetProviderRegistrationOptions[] {
public static createAssetProviderRegistrations(count = 10): IAssetProviderRegistrationOptions[] {
const registrations: IAssetProviderRegistrationOptions[] = [];
for (let i = 1; i <= count; i++) {
registrations.push(MockFactory.createAssetProviderRegistration(i.toString()));
@@ -722,7 +722,7 @@ export default class MockFactory {
* Creates an array of test regions
* @param count The number of regions to create (deafult: 5)
*/
public static createTestRegions(count: number = 5) {
public static createTestRegions(count = 5) {
const regions: IRegion[] = [];
for (let i = 1; i <= count; i++) {
regions.push(MockFactory.createTestRegion(`test${i}`));
@@ -873,7 +873,7 @@ export default class MockFactory {
* Creates test security tokens
* @param count The number of tokens to generate (default: 10)
*/
public static createSecurityTokens(count: number = 10): ISecurityToken[] {
public static createSecurityTokens(count = 10): ISecurityToken[] {
const securityTokens: ISecurityToken[] = [];
for (let i = 1; i <= 10; i++) {
securityTokens.push(MockFactory.createSecurityToken(i.toString()));
@@ -956,7 +956,7 @@ export default class MockFactory {
* @param predicate The predicate to evaluate the condition
* @param interval The interval to check the value
*/
public static waitForCondition(predicate: () => boolean, interval: number = 100): Promise<void> {
public static waitForCondition(predicate: () => boolean, interval = 100): Promise<void> {
return new Promise<void>((resolve, reject) => {
const handle = setInterval(() => {
try {
@@ -971,7 +971,7 @@ export default class MockFactory {
});
}
public static createAzureCustomVisionTags(count: number = 10): IAzureCustomVisionTag[] {
public static createAzureCustomVisionTags(count = 10): IAzureCustomVisionTag[] {
const tags: IAzureCustomVisionTag[] = [];
for (let i = 1; i <= count; i++) {
tags.push(MockFactory.createAzureCustomVisionTag(`Tag ${i}`));
@@ -989,7 +989,7 @@ export default class MockFactory {
};
}
public static createAzureCustomVisionRegions(count: number = 10): IAzureCustomVisionRegion[] {
public static createAzureCustomVisionRegions(count = 10): IAzureCustomVisionRegion[] {
const regions: IAzureCustomVisionRegion[] = [];
for (let i = 1; i <= count; i++) {
regions.push(MockFactory.createAzureCustomVisionRegion());
+1 -1
Ver Arquivo
@@ -143,5 +143,5 @@ function decryptProviderOptions<T = IProviderOptions>(providerOptions: IProvider
return providerOptions as T;
}
return decryptObject(providerOptions.encrypted, secret) as T;
return decryptObject(providerOptions.encrypted, secret);
}
+1 -1
Ver Arquivo
@@ -4,7 +4,7 @@ import { IpcProxyMessage } from "./ipcProxy";
export type IpcProxyHandler<T> = (sender: any, args: T) => any;
export class IpcMainProxy {
private static PROXY_EVENT_NAME: string = "ipc-renderer-proxy";
private static PROXY_EVENT_NAME = "ipc-renderer-proxy";
public handlers: { [type: string]: IpcProxyHandler<any> } = {};
+3 -3
Ver Arquivo
@@ -21,7 +21,7 @@ export type ImageObject = tf.Tensor3D | ImageData | HTMLImageElement | HTMLCanva
* Object Dectection loads active learning models and predicts regions
*/
export class ObjectDetection {
private modelLoaded: boolean = false;
private modelLoaded = false;
get loaded(): boolean {
return this.modelLoaded;
@@ -130,7 +130,7 @@ export class ObjectDetection {
* locations. Defaults to 20.
*
*/
public async detect(img: ImageObject, maxNumBoxes: number = 20): Promise<DetectedObject[]> {
public async detect(img: ImageObject, maxNumBoxes = 20): Promise<DetectedObject[]> {
if (this.model) {
return this.infer(img, maxNumBoxes);
}
@@ -147,7 +147,7 @@ export class ObjectDetection {
* objects. There can be multiple objects of the same class, but at different
* locations. Defaults to 20.
*/
private async infer(img: ImageObject, maxNumBoxes: number = 20): Promise<DetectedObject[]> {
private async infer(img: ImageObject, maxNumBoxes = 20): Promise<DetectedObject[]> {
const batched = tf.tidy(() => {
if (!(img instanceof tf.Tensor)) {
img = tf.browser.fromPixels(img);
+1 -1
Ver Arquivo
@@ -272,7 +272,7 @@ export class AzureBlobStorage implements IStorageProvider {
// tslint:disable-next-line:variable-name
_length?: number,
): Promise<string> {
const blob = await response.blobBody!;
const blob = await response.blobBody;
return this.blobToString(blob);
}
@@ -51,7 +51,7 @@ export class TFRecordAsset extends React.Component<IAssetProps, ITFRecordState>
const base64ImageData = await this.getTFRecordBase64Image(this.props.asset);
this.setState({
tfRecordImage64: base64ImageData,
hasError: !(!!base64ImageData),
hasError: !(base64ImageData),
});
} catch (e) {
this.setState({
@@ -4,16 +4,22 @@ import { mount, ReactWrapper } from "enzyme";
import { BrowserRouter as Router } from "react-router-dom";
describe("Conditional Nav Link", () => {
function createLink(to: string, disabled: boolean, props: any): ReactWrapper {
function createLink(
to: string,
disabled: boolean,
props: any
): ReactWrapper {
return mount(
<Router>
<ConditionalNavLink
disabled={disabled}
to={to}
title={props.title}>
<i className="fas fa-user" /> /* Example of child components */
title={props.title}
>
<i className="fas fa-user" />{" "}
{/* Example of child components */}
</ConditionalNavLink>
</Router>,
</Router>
);
}
@@ -1,5 +1,9 @@
import React from "react";
import { IAppError, ErrorCode, AppError } from "../../../../models/applicationState";
import {
IAppError,
ErrorCode,
AppError
} from "../../../../models/applicationState";
import { strings } from "../../../../common/strings";
import Alert from "../alert/alert";
import { Env } from "../../../../common/environment";
@@ -27,12 +31,19 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
public componentDidMount() {
window.addEventListener("error", this.onWindowError, true);
window.addEventListener("unhandledrejection", this.onUnhandedRejection, true);
window.addEventListener(
"unhandledrejection",
this.onUnhandedRejection,
true
);
}
public componentWillMount() {
public UNSAFE_componentWillMount() {
window.removeEventListener("error", this.onWindowError);
window.removeEventListener("unhandledrejection", this.onUnhandedRejection);
window.removeEventListener(
"unhandledrejection",
this.onUnhandedRejection
);
}
public render() {
@@ -47,11 +58,13 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
}
return (
<Alert title={localizedError ? localizedError.title : ""}
<Alert
title={localizedError ? localizedError.title : ""}
message={localizedError ? localizedError.message : ""}
closeButtonColor="secondary"
show={showError}
onClose={this.props.onClearError} />
onClose={this.props.onClearError}
/>
);
}
@@ -92,11 +105,11 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
}
let appError: IAppError = null;
// Promise rejection with reason
if (typeof (error) === "string") {
if (typeof error === "string") {
// Promise rejection with string base reason
appError = {
errorCode: ErrorCode.Unknown,
message: error || this.getUnknownErrorMessage(error),
message: error || this.getUnknownErrorMessage(error)
};
} else if (error instanceof AppError) {
// Promise rejection with AppError
@@ -104,21 +117,21 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
appError = {
title: reason.title || strings.errors.unknown.title,
errorCode: reason.errorCode,
message: reason.message || this.getUnknownErrorMessage(error),
message: reason.message || this.getUnknownErrorMessage(error)
};
} else if (error instanceof Error) {
// Promise rejection with other error like object
const reason = error as Error;
const reason = error;
appError = {
title: reason.name || strings.errors.unknown.title,
errorCode: ErrorCode.Unknown,
message: reason.message || this.getUnknownErrorMessage(error),
message: reason.message || this.getUnknownErrorMessage(error)
};
} else {
appError = {
title: strings.errors.unknown.title,
errorCode: ErrorCode.Unknown,
message: this.getUnknownErrorMessage(error),
message: this.getUnknownErrorMessage(error)
};
}
@@ -130,7 +143,7 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
private getUnknownErrorMessage(e) {
if (Env.get() !== "production") {
return (<pre>{JSON.stringify(e, null, 2)}</pre>);
return <pre>{JSON.stringify(e, null, 2)}</pre>;
} else {
return strings.errors.unknown.message;
}
@@ -151,11 +164,15 @@ export class ErrorHandler extends React.Component<IErrorHandlerProps> {
return {
errorCode: appError.errorCode,
message: localizedError.message,
title: localizedError.title,
title: localizedError.title
};
}
private isReactDnDError(e) {
return e && e.name === "Invariant Violation" && e.message === "Expected to find a valid target.";
return (
e &&
e.name === "Invariant Violation" &&
e.message === "Expected to find a valid target."
);
}
}
@@ -1,5 +1,9 @@
import React from "react";
import Form, { Widget, IChangeEvent, FormValidation } from "react-jsonschema-form";
import Form, {
Widget,
IChangeEvent,
FormValidation
} from "react-jsonschema-form";
import { IConnection } from "../../../../models/applicationState";
import LocalFolderPicker from "../../common/localFolderPicker/localFolderPicker";
import { strings, addLocValues } from "../../../../common/strings";
@@ -46,16 +50,19 @@ export interface IConnectionFormState {
/**
* Form for viewing, creating and editing connections
*/
export default class ConnectionForm extends React.Component<IConnectionFormProps, IConnectionFormState> {
export default class ConnectionForm extends React.Component<
IConnectionFormProps,
IConnectionFormState
> {
private widgets = {
localFolderPicker: (LocalFolderPicker as any) as Widget,
connectionProviderPicker: (ConnectionProviderPicker as any) as Widget,
protectedInput: (ProtectedInput as any) as Widget,
checkbox: CustomWidget(Checkbox, (props) => ({
checkbox: CustomWidget(Checkbox, props => ({
checked: props.value,
onChange: (value) => props.onChange(value.target.checked),
disabled: props.disabled,
})),
onChange: value => props.onChange(value.target.checked),
disabled: props.disabled
}))
};
constructor(props, context) {
@@ -65,8 +72,10 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
classNames: ["needs-validation"],
formSchema: { ...formSchema },
uiSchema: { ...uiSchema },
providerName: this.props.connection ? this.props.connection.providerType : null,
formData: this.props.connection,
providerName: this.props.connection
? this.props.connection.providerType
: null,
formData: this.props.connection
};
if (this.props.connection) {
@@ -88,27 +97,39 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
return (
<div className="app-connections-page-detail m-3">
<h3>
<i className="fas fa-plug fa-1x"></i>
<span className="px-2">
{strings.connections.settings}
</span>
<i className="fas fa-plug fa-1x" />
<span className="px-2">{strings.connections.settings}</span>
</h3>
<div className="m-3">
{ isBrowser() && this.state.providerName === "bingImageSearch" &&
<div className="alert alert-warning" role="alert">
<i className="fas fa-exclamation-circle mr-1" aria-hidden="true"></i>
{ strings.connections.imageCorsWarning }
</div>
}
{ isBrowser() && this.state.providerName === "azureBlobStorage" &&
<div className="alert alert-warning" role="alert">
<i className="fas fa-exclamation-circle mr-1" aria-hidden="true"></i>
{ strings.formatString(
strings.connections.blobCorsWarning,
<a href="https://aka.ms/blob-cors" target="_blank">{strings.connections.azDocLinkText}</a>)
}
</div>
}
{isBrowser() &&
this.state.providerName === "bingImageSearch" && (
<div className="alert alert-warning" role="alert">
<i
className="fas fa-exclamation-circle mr-1"
aria-hidden="true"
/>
{strings.connections.imageCorsWarning}
</div>
)}
{isBrowser() &&
this.state.providerName === "azureBlobStorage" && (
<div className="alert alert-warning" role="alert">
<i
className="fas fa-exclamation-circle mr-1"
aria-hidden="true"
/>
{strings.formatString(
strings.connections.blobCorsWarning,
<a
href="https://aka.ms/blob-cors"
target="_blank"
rel="noreferrer"
>
{strings.connections.azDocLinkText}
</a>
)}
</div>
)}
<Form
className={this.state.classNames.join(" ")}
showErrorList={false}
@@ -121,12 +142,22 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
uiSchema={this.state.uiSchema}
formData={this.state.formData}
onChange={this.onFormChange}
onSubmit={(form) => this.props.onSubmit(form.formData)}>
onSubmit={form => this.props.onSubmit(form.formData)}
>
<div>
<button className="btn btn-success mr-1" type="submit">{strings.connections.save}</button>
<button className="btn btn-secondary btn-cancel"
<button
className="btn btn-success mr-1"
type="submit"
>
{strings.connections.save}
</button>
<button
className="btn btn-secondary btn-cancel"
type="button"
onClick={this.onFormCancel}>{strings.common.cancel}</button>
onClick={this.onFormCancel}
>
{strings.common.cancel}
</button>
</div>
</Form>
</div>
@@ -141,7 +172,7 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
if (this.state.classNames.indexOf("was-validated") === -1) {
this.setState({
classNames: [...this.state.classNames, "was-validated"],
classNames: [...this.state.classNames, "was-validated"]
});
}
@@ -155,10 +186,10 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
this.bindForm(args.formData, true);
} else {
this.setState({
formData: args.formData,
formData: args.formData
});
}
}
};
private onFormCancel() {
if (this.props.onCancel) {
@@ -166,14 +197,18 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
}
}
private bindForm(connection: IConnection, resetProviderOptions: boolean = false) {
private bindForm(connection: IConnection, resetProviderOptions = false) {
const providerType = connection ? connection.providerType : null;
let newFormSchema: any = this.state.formSchema;
let newUiSchema: any = this.state.uiSchema;
if (providerType) {
const providerSchema = addLocValues(require(`../../../../providers/storage/${providerType}.json`));
const providerUiSchema = addLocValues(require(`../../../../providers/storage/${providerType}.ui.json`));
const providerSchema = addLocValues(
require(`../../../../providers/storage/${providerType}.json`)
);
const providerUiSchema = addLocValues(
require(`../../../../providers/storage/${providerType}.ui.json`)
);
newFormSchema = { ...formSchema };
newFormSchema.properties["providerOptions"] = providerSchema;
@@ -199,7 +234,7 @@ export default class ConnectionForm extends React.Component<IConnectionFormProps
providerName: providerType,
formSchema: newFormSchema,
uiSchema: newUiSchema,
formData,
formData
});
}
}
@@ -19,8 +19,8 @@ import ConnectionPage, { IConnectionPageProps } from "./connectionsPage";
import { toast } from "react-toastify";
describe("Connections Page", () => {
const connectionsRoute: string = "/connections";
const connectionCreateRoute: string = "/connections/create";
const connectionsRoute = "/connections";
const connectionCreateRoute = "/connections/create";
function createComponent(routerContext, route, store, props: IConnectionPageProps): ReactWrapper {
return mount(
@@ -178,7 +178,7 @@ describe("Editor Canvas", () => {
},
selectedAsset: assetMetadata,
});
const canvas = wrapper.instance() as Canvas;
const canvas = wrapper.instance();
expect(wrapper.state().currentAsset).toEqual(assetMetadata);
expect(() => canvas.updateCanvasToolsRegionTags()).not.toThrowError();
});
@@ -537,7 +537,7 @@ describe("Editor Canvas", () => {
it("Copies currently selected regions to clipboard", () => {
const wrapper = createComponent();
const canvas = wrapper.instance() as Canvas;
const canvas = wrapper.instance();
mockSelectedRegions(["test1"]);
const region1 = wrapper.state().currentAsset.regions.find((r) => r.id === "test1");
@@ -561,7 +561,7 @@ describe("Editor Canvas", () => {
},
});
const canvas = wrapper.instance() as Canvas;
const canvas = wrapper.instance();
mockSelectedRegions([]);
canvas.pasteRegions();
@@ -597,7 +597,7 @@ describe("Editor Canvas", () => {
const original: IAssetMetadata = {
...wrapper.prop("selectedAsset"),
};
const canvas = wrapper.instance() as Canvas;
const canvas = wrapper.instance();
const region1 = wrapper.state().currentAsset.regions.find((r) => r.id === "test1");
mockSelectedRegions(["test1"]);
@@ -868,7 +868,7 @@ describe("Editor Page Component", () => {
});
});
function createStore(project: IProject, setCurrentProject: boolean = false): Store<any, AnyAction> {
function createStore(project: IProject, setCurrentProject = false): Store<any, AnyAction> {
const initialState: IApplicationState = {
currentProject: setCurrentProject ? project : null,
appSettings: MockFactory.appSettings(),
@@ -118,7 +118,7 @@ export default class EditorPage extends React.Component<IEditorPageProps, IEdito
};
private activeLearningService: ActiveLearningService = null;
private loadingProjectAssets: boolean = false;
private loadingProjectAssets = false;
private toolbarItems: IToolbarItemRegistration[] = ToolbarItemFactory.getToolbarItems();
private canvas: RefObject<Canvas> = React.createRef();
private renameTagConfirm: React.RefObject<Confirm> = React.createRef();
@@ -140,7 +140,7 @@ export default class ExportForm extends React.Component<IExportFormProps, IExpor
}
}
private bindForm = (exportFormat: IExportFormat, resetProviderOptions: boolean = false): void => {
private bindForm = (exportFormat: IExportFormat, resetProviderOptions = false): void => {
// If no provider type was specified on bind, pick the default provider
const providerType = (exportFormat && exportFormat.providerType)
? exportFormat.providerType
@@ -139,7 +139,7 @@ function createProps(projectId: string): IExportPageProps {
};
}
function createStore(project: IProject, setCurrentProject: boolean = false): Store<any, AnyAction> {
function createStore(project: IProject, setCurrentProject = false): Store<any, AnyAction> {
const initialState: IApplicationState = {
currentProject: setCurrentProject ? project : null,
appSettings: MockFactory.appSettings(),
@@ -124,7 +124,7 @@ export default class ProjectSettingsPage extends React.Component<IProjectSetting
}
private onFormSubmit = async (project: IProject) => {
const isNew = !(!!project.id);
const isNew = !(project.id);
await this.props.applicationActions.ensureSecurityToken(project);
await this.props.projectActions.saveProject(project);
@@ -148,7 +148,7 @@ export default class ProjectSettingsPage extends React.Component<IProjectSetting
* Checks whether a project is partially populated
*/
private isPartialProject = (project: IProject): boolean => {
return project && !(!!project.id) &&
return project && !(project.id) &&
(
!!project.name
|| !!project.description
+1 -1
Ver Arquivo
@@ -20,7 +20,7 @@ export class HelpMenu extends React.Component<IHelpMenuProps, IHelpMenuState> {
public state = {
show: false,
};
private icon: string = "fa-question-circle";
private icon = "fa-question-circle";
public render() {
return (
@@ -14,7 +14,7 @@ import ConnectionsPage from "./../pages/connections/connectionsPage";
import { IApplicationState } from "./../../../models/applicationState";
describe("Main Content Router", () => {
const badRoute: string = "/index.html";
const badRoute = "/index.html";
function createComponent(routerContext, route, store, props: IHomePageProps): ReactWrapper {
return mount(
+1 -1
Ver Arquivo
@@ -32,7 +32,7 @@ export class TitleBar extends React.Component<ITitleBarProps, ITitleBarState> {
private currentWindow: Electron.BrowserWindow;
public componentDidMount() {
const isElectron: boolean = !!window["require"];
const isElectron = !!window["require"];
if (isElectron) {
this.remote = (window as any).require("electron").remote as Electron.Remote;
+1 -1
Ver Arquivo
@@ -13,7 +13,7 @@ import { Env } from "../../common/environment";
*/
export default function createReduxStore(
initialState?: IApplicationState,
useLocalStorage: boolean = false): Store {
useLocalStorage = false): Store {
const paths: string[] = ["appSettings", "connections", "recentProjects"];
let middlewares = [thunk, createAppInsightsLogger()];
+1 -1
Ver Arquivo
@@ -6,7 +6,7 @@ import { Env } from "../common/environment";
export class ActiveLearningService {
private objectDetection: ObjectDetection;
private modelLoaded: boolean = false;
private modelLoaded = false;
constructor(private settings: IActiveLearningSettings) {
Guard.null(settings);
+1 -1
Ver Arquivo
@@ -102,7 +102,7 @@ describe("Import Service", () => {
const v2Project = await importService.convertProject({ file, content });
const results = await importService.generateAssets(fileInfo, v2Project);
const parentAssets = results.filter((assetMetadata) => !(!!assetMetadata.asset.parent));
const parentAssets = results.filter((assetMetadata) => !(assetMetadata.asset.parent));
const childAssets = results.filter((assetMetadata) => !!assetMetadata.asset.parent);
expect(parentAssets).toHaveLength(1);
+3 -11
Ver Arquivo
@@ -14,16 +14,8 @@
"noEmit": true,
"jsx": "preserve",
"experimentalDecorators": true,
"lib": [
"es2015",
"dom"
],
"typeRoots": [
"./typings",
"./node_modules/@types"
],
"lib": ["es2015", "dom"],
"typeRoots": ["./typings", "./node_modules/@types"]
},
"include": [
"src"
]
"include": ["src"]
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
7 ESLint rules behave differently from their TSLint counterparts:
* @typescript-eslint/no-unused-expressions:
- The TSLint optional config "allow-new" is the default ESLint behavior and will no longer be ignored.
* camelcase:
- Leading and trailing underscores (_) in variable names will now be ignored.
- ESLint's camel-case rule does not allow pascal or snake case variable names. Those cases are reserved for class names and static methods.
* eqeqeq:
- Option "smart" allows for comparing two literal values, evaluating the value of typeof and null comparisons.
* no-invalid-this:
- Functions in methods will no longer be ignored.
* no-underscore-dangle:
- Leading or trailing underscores (_) on identifiers will now be forbidden.
* prefer-arrow/prefer-arrow-functions:
- ESLint does not support allowing standalone function declarations.
- ESLint does not support allowing named functions defined with the function keyword.
* space-before-function-paren:
- Option "constructor" is not supported by ESLint.
- Option "method" is not supported by ESLint.
2 rules are not known by tslint-to-eslint-config to have ESLint equivalents:
* tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "import-spacing".
* tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "whitespace".
1 editor setting is not known by tslint-to-eslint-config to have an ESLint equivalent:
* tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "editor.formatOnSave".
-17
Ver Arquivo
@@ -1,17 +0,0 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {},
"rules": {
"object-literal-sort-keys": false,
"no-console": false,
"no-shadowed-variable": false,
"ordered-imports": false,
"no-string-literal": false,
"no-bitwise": false,
"function-constructor": false
},
"rulesDirectory": []
}