From eba59ae622bcada03bbda1f49524ac329682344b Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Wed, 27 May 2020 15:43:28 +0200 Subject: [PATCH] better linting (#72) Improve linting and fix linting errors Signed-off-by: Philip Molares Signed-off-by: Tilman Vatteroth --- .editorconfig | 437 ++++++++++++++++++ .github/workflows/build.yml | 27 ++ package.json | 30 +- src/api/config.ts | 24 +- src/api/user.ts | 115 ++--- .../application-loader/application-loader.tsx | 58 +-- .../application-loader/loading-screen.tsx | 34 +- .../element-separator/element-separator.tsx | 44 +- src/components/icon-button/icon-button.tsx | 38 +- .../landing/layout/footer/external-link.tsx | 45 +- .../landing/layout/footer/footer.tsx | 22 +- .../landing/layout/footer/language-picker.tsx | 94 ++-- .../layout/footer/powered-by-links.tsx | 76 ++- .../landing/layout/footer/social-links.tsx | 30 +- .../landing/layout/footer/translated-link.tsx | 30 +- src/components/landing/layout/index.tsx | 54 +-- .../navigation/header-bar/header-bar.tsx | 88 ++-- .../layout/navigation/header-nav-link.tsx | 24 +- .../navigation/new-guest-note-button.tsx | 36 +- .../navigation/new-user-note-button.tsx | 38 +- .../layout/navigation/sign-in-button.tsx | 30 +- .../user-dropdown/user-dropdown.tsx | 96 ++-- .../landing/layout/style/font-pack.scss | 2 +- .../pages/history/common/close-button.tsx | 30 +- .../pages/history/common/pin-button.tsx | 34 +- .../history-card/history-card-list.tsx | 39 +- .../history/history-card/history-card.tsx | 68 +-- .../history-content/history-content.tsx | 93 ++-- .../history-table/history-table-row.tsx | 56 +-- .../history/history-table/history-table.tsx | 62 +-- .../history-toolbar/history-toolbar.tsx | 203 ++++---- .../landing/pages/history/history.tsx | 108 ++--- .../intro/cover-buttons/cover-buttons.tsx | 77 ++- .../landing/pages/intro/feature-links.tsx | 68 +-- src/components/landing/pages/intro/intro.tsx | 41 +- .../social-link-button/social-link-button.tsx | 40 +- .../landing/pages/login/auth/via-email.tsx | 118 +++-- .../landing/pages/login/auth/via-ldap.tsx | 134 +++--- .../pages/login/auth/via-one-click.tsx | 196 ++++---- .../landing/pages/login/auth/via-openid.tsx | 102 ++-- src/components/landing/pages/login/login.tsx | 150 +++--- src/components/pagination/pager-item.tsx | 21 +- .../pagination/pager-pagination.tsx | 136 +++--- src/components/pagination/pager.tsx | 31 +- src/components/sort-button/sort-button.tsx | 54 +-- src/index.tsx | 36 +- src/initializers/configLoader.ts | 34 +- src/initializers/fontAwesome.ts | 74 +-- src/initializers/i18n.ts | 98 ++-- src/initializers/index.ts | 26 +- src/redux/backend-config/methods.ts | 20 +- src/redux/backend-config/reducers.ts | 68 +-- src/redux/backend-config/types.ts | 4 +- src/redux/frontend-config/methods.ts | 18 +- src/redux/frontend-config/reducers.ts | 22 +- src/redux/frontend-config/types.ts | 4 +- src/redux/index.ts | 28 +- src/redux/modal/methods.ts | 8 +- src/redux/modal/reducers.ts | 28 +- src/redux/modal/types.ts | 4 +- src/redux/user/methods.ts | 32 +- src/redux/user/reducers.ts | 39 +- src/redux/user/types.ts | 12 +- src/service-worker.ts | 79 ++-- src/setup-tests.ts | 2 +- src/utils/apiUtils.ts | 39 +- src/utils/historyUtils.ts | 136 +++--- src/utils/iconProp.ts | 4 + src/utils/store.ts | 6 +- yarn.lock | 126 ++++- 70 files changed, 2413 insertions(+), 1867 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/build.yml create mode 100644 src/utils/iconProp.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..7a6a8485e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,437 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 120 +tab_width = 4 +trim_trailing_whitespace = true +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_wrap_on_typing = false + +[*.css] +ij_css_align_closing_brace_with_properties = false +ij_css_blank_lines_around_nested_selector = 1 +ij_css_blank_lines_between_blocks = 1 +ij_css_brace_placement = end_of_line +ij_css_enforce_quotes_on_format = false +ij_css_hex_color_long_format = false +ij_css_hex_color_lower_case = false +ij_css_hex_color_short_format = false +ij_css_hex_color_upper_case = false +ij_css_keep_blank_lines_in_code = 2 +ij_css_keep_indents_on_empty_lines = false +ij_css_keep_single_line_blocks = false +ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_css_space_after_colon = true +ij_css_space_before_opening_brace = true +ij_css_use_double_quotes = true +ij_css_value_alignment = do_not_align + +[*.scss] +indent_size = 2 +ij_scss_align_closing_brace_with_properties = false +ij_scss_blank_lines_around_nested_selector = 1 +ij_scss_blank_lines_between_blocks = 1 +ij_scss_brace_placement = 0 +ij_scss_enforce_quotes_on_format = false +ij_scss_hex_color_long_format = false +ij_scss_hex_color_lower_case = false +ij_scss_hex_color_short_format = false +ij_scss_hex_color_upper_case = false +ij_scss_keep_blank_lines_in_code = 2 +ij_scss_keep_indents_on_empty_lines = false +ij_scss_keep_single_line_blocks = false +ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_scss_space_after_colon = true +ij_scss_space_before_opening_brace = true +ij_scss_use_double_quotes = true +ij_scss_value_alignment = 0 + +[{*.ats,*.ts,*.tsx}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_typescript_align_imports = false +ij_typescript_align_multiline_array_initializer_expression = false +ij_typescript_align_multiline_binary_operation = false +ij_typescript_align_multiline_chained_methods = false +ij_typescript_align_multiline_extends_list = false +ij_typescript_align_multiline_for = true +ij_typescript_align_multiline_parameters = true +ij_typescript_align_multiline_parameters_in_calls = false +ij_typescript_align_multiline_ternary_operation = false +ij_typescript_align_object_properties = 0 +ij_typescript_align_union_types = false +ij_typescript_align_var_statements = 0 +ij_typescript_array_initializer_new_line_after_left_brace = false +ij_typescript_array_initializer_right_brace_on_new_line = false +ij_typescript_array_initializer_wrap = off +ij_typescript_assignment_wrap = off +ij_typescript_binary_operation_sign_on_next_line = false +ij_typescript_binary_operation_wrap = off +ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_typescript_blank_lines_after_imports = 1 +ij_typescript_blank_lines_around_class = 1 +ij_typescript_blank_lines_around_field = 0 +ij_typescript_blank_lines_around_field_in_interface = 0 +ij_typescript_blank_lines_around_function = 1 +ij_typescript_blank_lines_around_method = 1 +ij_typescript_blank_lines_around_method_in_interface = 1 +ij_typescript_block_brace_style = end_of_line +ij_typescript_call_parameters_new_line_after_left_paren = false +ij_typescript_call_parameters_right_paren_on_new_line = false +ij_typescript_call_parameters_wrap = off +ij_typescript_catch_on_new_line = false +ij_typescript_chained_call_dot_on_new_line = true +ij_typescript_class_brace_style = end_of_line +ij_typescript_comma_on_new_line = false +ij_typescript_do_while_brace_force = never +ij_typescript_else_on_new_line = false +ij_typescript_enforce_trailing_comma = keep +ij_typescript_extends_keyword_wrap = off +ij_typescript_extends_list_wrap = off +ij_typescript_field_prefix = _ +ij_typescript_file_name_style = relaxed +ij_typescript_finally_on_new_line = false +ij_typescript_for_brace_force = never +ij_typescript_for_statement_new_line_after_left_paren = false +ij_typescript_for_statement_right_paren_on_new_line = false +ij_typescript_for_statement_wrap = off +ij_typescript_force_quote_style = false +ij_typescript_force_semicolon_style = true +ij_typescript_function_expression_brace_style = end_of_line +ij_typescript_if_brace_force = never +ij_typescript_import_merge_members = global +ij_typescript_import_prefer_absolute_path = global +ij_typescript_import_sort_members = true +ij_typescript_import_sort_module_name = true +ij_typescript_import_use_node_resolution = true +ij_typescript_imports_wrap = on_every_item +ij_typescript_indent_case_from_switch = true +ij_typescript_indent_chained_calls = false +ij_typescript_indent_package_children = 0 +ij_typescript_jsdoc_include_types = false +ij_typescript_jsx_attribute_value = braces +ij_typescript_keep_blank_lines_in_code = 1 +ij_typescript_keep_first_column_comment = true +ij_typescript_keep_indents_on_empty_lines = false +ij_typescript_keep_line_breaks = true +ij_typescript_keep_simple_blocks_in_one_line = false +ij_typescript_keep_simple_methods_in_one_line = false +ij_typescript_line_comment_add_space = true +ij_typescript_line_comment_at_first_column = false +ij_typescript_method_brace_style = end_of_line +ij_typescript_method_call_chain_wrap = off +ij_typescript_method_parameters_new_line_after_left_paren = false +ij_typescript_method_parameters_right_paren_on_new_line = false +ij_typescript_method_parameters_wrap = off +ij_typescript_object_literal_wrap = on_every_item +ij_typescript_parentheses_expression_new_line_after_left_paren = false +ij_typescript_parentheses_expression_right_paren_on_new_line = false +ij_typescript_place_assignment_sign_on_next_line = false +ij_typescript_prefer_as_type_cast = false +ij_typescript_prefer_explicit_types_function_expression_returns = false +ij_typescript_prefer_explicit_types_function_returns = false +ij_typescript_prefer_explicit_types_vars_fields = false +ij_typescript_prefer_parameters_wrap = false +ij_typescript_reformat_c_style_comments = false +ij_typescript_space_after_colon = true +ij_typescript_space_after_comma = true +ij_typescript_space_after_dots_in_rest_parameter = false +ij_typescript_space_after_generator_mult = true +ij_typescript_space_after_property_colon = true +ij_typescript_space_after_quest = true +ij_typescript_space_after_type_colon = true +ij_typescript_space_after_unary_not = false +ij_typescript_space_before_async_arrow_lparen = true +ij_typescript_space_before_catch_keyword = true +ij_typescript_space_before_catch_left_brace = true +ij_typescript_space_before_catch_parentheses = true +ij_typescript_space_before_class_lbrace = true +ij_typescript_space_before_class_left_brace = true +ij_typescript_space_before_colon = true +ij_typescript_space_before_comma = false +ij_typescript_space_before_do_left_brace = true +ij_typescript_space_before_else_keyword = true +ij_typescript_space_before_else_left_brace = true +ij_typescript_space_before_finally_keyword = true +ij_typescript_space_before_finally_left_brace = true +ij_typescript_space_before_for_left_brace = true +ij_typescript_space_before_for_parentheses = true +ij_typescript_space_before_for_semicolon = false +ij_typescript_space_before_function_left_parenth = true +ij_typescript_space_before_generator_mult = false +ij_typescript_space_before_if_left_brace = true +ij_typescript_space_before_if_parentheses = true +ij_typescript_space_before_method_call_parentheses = false +ij_typescript_space_before_method_left_brace = true +ij_typescript_space_before_method_parentheses = true +ij_typescript_space_before_property_colon = false +ij_typescript_space_before_quest = true +ij_typescript_space_before_switch_left_brace = true +ij_typescript_space_before_switch_parentheses = true +ij_typescript_space_before_try_left_brace = true +ij_typescript_space_before_type_colon = false +ij_typescript_space_before_unary_not = false +ij_typescript_space_before_while_keyword = true +ij_typescript_space_before_while_left_brace = true +ij_typescript_space_before_while_parentheses = true +ij_typescript_spaces_around_additive_operators = true +ij_typescript_spaces_around_arrow_function_operator = true +ij_typescript_spaces_around_assignment_operators = true +ij_typescript_spaces_around_bitwise_operators = true +ij_typescript_spaces_around_equality_operators = true +ij_typescript_spaces_around_logical_operators = true +ij_typescript_spaces_around_multiplicative_operators = true +ij_typescript_spaces_around_relational_operators = true +ij_typescript_spaces_around_shift_operators = true +ij_typescript_spaces_around_unary_operator = false +ij_typescript_spaces_within_array_initializer_brackets = false +ij_typescript_spaces_within_brackets = false +ij_typescript_spaces_within_catch_parentheses = false +ij_typescript_spaces_within_for_parentheses = false +ij_typescript_spaces_within_if_parentheses = false +ij_typescript_spaces_within_imports = true +ij_typescript_spaces_within_interpolation_expressions = false +ij_typescript_spaces_within_method_call_parentheses = false +ij_typescript_spaces_within_method_parentheses = false +ij_typescript_spaces_within_object_literal_braces = true +ij_typescript_spaces_within_object_type_braces = true +ij_typescript_spaces_within_parentheses = false +ij_typescript_spaces_within_switch_parentheses = false +ij_typescript_spaces_within_type_assertion = false +ij_typescript_spaces_within_union_types = true +ij_typescript_spaces_within_while_parentheses = false +ij_typescript_special_else_if_treatment = true +ij_typescript_ternary_operation_signs_on_next_line = false +ij_typescript_ternary_operation_wrap = off +ij_typescript_union_types_wrap = on_every_item +ij_typescript_use_chained_calls_group_indents = false +ij_typescript_use_double_quotes = false +ij_typescript_use_explicit_js_extension = global +ij_typescript_use_path_mapping = always +ij_typescript_use_public_modifier = false +ij_typescript_use_semicolon_after_statement = false +ij_typescript_var_declaration_wrap = normal +ij_typescript_while_brace_force = never +ij_typescript_while_on_new_line = false +ij_typescript_wrap_comments = false + +[{*.cjs,*.js}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 2 +ij_javascript_align_imports = false +ij_javascript_align_multiline_array_initializer_expression = false +ij_javascript_align_multiline_binary_operation = false +ij_javascript_align_multiline_chained_methods = false +ij_javascript_align_multiline_extends_list = false +ij_javascript_align_multiline_for = true +ij_javascript_align_multiline_parameters = true +ij_javascript_align_multiline_parameters_in_calls = false +ij_javascript_align_multiline_ternary_operation = false +ij_javascript_align_object_properties = 0 +ij_javascript_align_union_types = false +ij_javascript_align_var_statements = 0 +ij_javascript_array_initializer_new_line_after_left_brace = false +ij_javascript_array_initializer_right_brace_on_new_line = false +ij_javascript_array_initializer_wrap = off +ij_javascript_assignment_wrap = off +ij_javascript_binary_operation_sign_on_next_line = false +ij_javascript_binary_operation_wrap = off +ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_javascript_blank_lines_after_imports = 1 +ij_javascript_blank_lines_around_class = 1 +ij_javascript_blank_lines_around_field = 0 +ij_javascript_blank_lines_around_function = 1 +ij_javascript_blank_lines_around_method = 1 +ij_javascript_block_brace_style = end_of_line +ij_javascript_call_parameters_new_line_after_left_paren = false +ij_javascript_call_parameters_right_paren_on_new_line = false +ij_javascript_call_parameters_wrap = off +ij_javascript_catch_on_new_line = false +ij_javascript_chained_call_dot_on_new_line = true +ij_javascript_class_brace_style = end_of_line +ij_javascript_comma_on_new_line = false +ij_javascript_do_while_brace_force = never +ij_javascript_else_on_new_line = false +ij_javascript_enforce_trailing_comma = keep +ij_javascript_extends_keyword_wrap = off +ij_javascript_extends_list_wrap = off +ij_javascript_field_prefix = _ +ij_javascript_file_name_style = relaxed +ij_javascript_finally_on_new_line = false +ij_javascript_for_brace_force = never +ij_javascript_for_statement_new_line_after_left_paren = false +ij_javascript_for_statement_right_paren_on_new_line = false +ij_javascript_for_statement_wrap = off +ij_javascript_force_quote_style = true +ij_javascript_force_semicolon_style = true +ij_javascript_function_expression_brace_style = end_of_line +ij_javascript_if_brace_force = never +ij_javascript_import_merge_members = global +ij_javascript_import_prefer_absolute_path = global +ij_javascript_import_sort_members = true +ij_javascript_import_sort_module_name = false +ij_javascript_import_use_node_resolution = true +ij_javascript_imports_wrap = on_every_item +ij_javascript_indent_case_from_switch = true +ij_javascript_indent_chained_calls = true +ij_javascript_indent_package_children = 0 +ij_javascript_jsx_attribute_value = braces +ij_javascript_keep_blank_lines_in_code = 1 +ij_javascript_keep_first_column_comment = true +ij_javascript_keep_indents_on_empty_lines = false +ij_javascript_keep_line_breaks = true +ij_javascript_keep_simple_blocks_in_one_line = true +ij_javascript_keep_simple_methods_in_one_line = true +ij_javascript_line_comment_add_space = true +ij_javascript_line_comment_at_first_column = false +ij_javascript_method_brace_style = end_of_line +ij_javascript_method_call_chain_wrap = off +ij_javascript_method_parameters_new_line_after_left_paren = false +ij_javascript_method_parameters_right_paren_on_new_line = false +ij_javascript_method_parameters_wrap = off +ij_javascript_object_literal_wrap = on_every_item +ij_javascript_parentheses_expression_new_line_after_left_paren = false +ij_javascript_parentheses_expression_right_paren_on_new_line = false +ij_javascript_place_assignment_sign_on_next_line = false +ij_javascript_prefer_as_type_cast = false +ij_javascript_prefer_explicit_types_function_expression_returns = false +ij_javascript_prefer_explicit_types_function_returns = false +ij_javascript_prefer_explicit_types_vars_fields = false +ij_javascript_prefer_parameters_wrap = false +ij_javascript_reformat_c_style_comments = false +ij_javascript_space_after_colon = true +ij_javascript_space_after_comma = true +ij_javascript_space_after_dots_in_rest_parameter = false +ij_javascript_space_after_generator_mult = true +ij_javascript_space_after_property_colon = true +ij_javascript_space_after_quest = true +ij_javascript_space_after_type_colon = true +ij_javascript_space_after_unary_not = false +ij_javascript_space_before_async_arrow_lparen = true +ij_javascript_space_before_catch_keyword = true +ij_javascript_space_before_catch_left_brace = true +ij_javascript_space_before_catch_parentheses = true +ij_javascript_space_before_class_lbrace = true +ij_javascript_space_before_class_left_brace = true +ij_javascript_space_before_colon = true +ij_javascript_space_before_comma = false +ij_javascript_space_before_do_left_brace = true +ij_javascript_space_before_else_keyword = true +ij_javascript_space_before_else_left_brace = true +ij_javascript_space_before_finally_keyword = true +ij_javascript_space_before_finally_left_brace = true +ij_javascript_space_before_for_left_brace = true +ij_javascript_space_before_for_parentheses = true +ij_javascript_space_before_for_semicolon = false +ij_javascript_space_before_function_left_parenth = true +ij_javascript_space_before_generator_mult = true +ij_javascript_space_before_if_left_brace = true +ij_javascript_space_before_if_parentheses = true +ij_javascript_space_before_method_call_parentheses = false +ij_javascript_space_before_method_left_brace = true +ij_javascript_space_before_method_parentheses = true +ij_javascript_space_before_property_colon = false +ij_javascript_space_before_quest = true +ij_javascript_space_before_switch_left_brace = true +ij_javascript_space_before_switch_parentheses = true +ij_javascript_space_before_try_left_brace = true +ij_javascript_space_before_type_colon = false +ij_javascript_space_before_unary_not = false +ij_javascript_space_before_while_keyword = true +ij_javascript_space_before_while_left_brace = true +ij_javascript_space_before_while_parentheses = true +ij_javascript_spaces_around_additive_operators = true +ij_javascript_spaces_around_arrow_function_operator = true +ij_javascript_spaces_around_assignment_operators = true +ij_javascript_spaces_around_bitwise_operators = true +ij_javascript_spaces_around_equality_operators = true +ij_javascript_spaces_around_logical_operators = true +ij_javascript_spaces_around_multiplicative_operators = true +ij_javascript_spaces_around_relational_operators = true +ij_javascript_spaces_around_shift_operators = true +ij_javascript_spaces_around_unary_operator = false +ij_javascript_spaces_within_array_initializer_brackets = false +ij_javascript_spaces_within_brackets = false +ij_javascript_spaces_within_catch_parentheses = false +ij_javascript_spaces_within_for_parentheses = false +ij_javascript_spaces_within_if_parentheses = false +ij_javascript_spaces_within_imports = true +ij_javascript_spaces_within_interpolation_expressions = false +ij_javascript_spaces_within_method_call_parentheses = false +ij_javascript_spaces_within_method_parentheses = false +ij_javascript_spaces_within_object_literal_braces = true +ij_javascript_spaces_within_object_type_braces = true +ij_javascript_spaces_within_parentheses = false +ij_javascript_spaces_within_switch_parentheses = false +ij_javascript_spaces_within_type_assertion = false +ij_javascript_spaces_within_union_types = true +ij_javascript_spaces_within_while_parentheses = false +ij_javascript_special_else_if_treatment = true +ij_javascript_ternary_operation_signs_on_next_line = true +ij_javascript_ternary_operation_wrap = off +ij_javascript_union_types_wrap = on_every_item +ij_javascript_use_chained_calls_group_indents = false +ij_javascript_use_double_quotes = false +ij_javascript_use_explicit_js_extension = global +ij_javascript_use_path_mapping = always +ij_javascript_use_public_modifier = false +ij_javascript_use_semicolon_after_statement = false +ij_javascript_var_declaration_wrap = normal +ij_javascript_while_brace_force = never +ij_javascript_while_on_new_line = false +ij_javascript_wrap_comments = false + +[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] +ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p +ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span,pre,textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = false +ij_html_text_wrap = normal + +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..1dd3435d6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,27 @@ +name: lint and build + +on: + push: + branches: [master, dev] + pull_request: + branches: [master, dev] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Cache node_modules + uses: actions/cache@v1.1.0 + with: + path: node_modules + key: node_modules + - name: Install dependencies + uses: borales/actions-yarn@v2.1.0 + with: + cmd: install + - name: build project + uses: borales/actions-yarn@v2.1.0 + with: + cmd: build diff --git a/package.json b/package.json index 40c0afd1f..7600458cb 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,25 @@ "eject": "react-scripts eject" }, "eslintConfig": { - "extends": "react-app" + "parserOptions": { + "tsconfigRootDir": "", + "project": [ + "./tsconfig.json" + ] + }, + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "react-app", + "standard", + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:import/recommended", + "plugin:import/typescript" + ] }, "browserslist": { "production": [ @@ -64,6 +82,16 @@ "devDependencies": { "@types/redux-devtools": "^3.0.47", "@types/redux-devtools-extension": "^2.13.2", + "@typescript-eslint/eslint-plugin": "^3.0.0", + "@typescript-eslint/parser": "^3.0.0", + "eslint-config-react-app": "^5.2.1", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-flowtype": "^5.1.0", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", "redux-devtools": "^3.5.0", "redux-devtools-extension": "^2.13.8" } diff --git a/src/api/config.ts b/src/api/config.ts index 9ba43ec03..7cb35c9d4 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -1,15 +1,15 @@ -import {FrontendConfigState} from "../redux/frontend-config/types"; -import {BackendConfigState} from "../redux/backend-config/types"; -import {expectResponseCode, getBackendUrl} from "../utils/apiUtils"; +import { FrontendConfigState } from '../redux/frontend-config/types' +import { BackendConfigState } from '../redux/backend-config/types' +import { expectResponseCode, getBackendUrl } from '../utils/apiUtils' -export const getBackendConfig = async () => { - const response = await fetch(getBackendUrl() + '/backend-config.json'); - expectResponseCode(response); - return await response.json() as Promise; +export const getBackendConfig: () => Promise = async () => { + const response = await fetch(getBackendUrl() + '/backend-config.json') + expectResponseCode(response) + return await response.json() as Promise } -export const getFrontendConfig = async () => { - const response = await fetch('config.json'); - expectResponseCode(response) - return await response.json() as Promise; -} \ No newline at end of file +export const getFrontendConfig: () => Promise = async () => { + const response = await fetch('config.json') + expectResponseCode(response) + return await response.json() as Promise +} diff --git a/src/api/user.ts b/src/api/user.ts index d77536f78..c80ba106e 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -1,67 +1,72 @@ -import {expectResponseCode, getBackendUrl} from "../utils/apiUtils"; +import { expectResponseCode, getBackendUrl } from '../utils/apiUtils' -export const getMe = async () => { - return fetch('/me'); +export const getMe: (() => Promise) = async () => { + const response = await fetch('/me') + expectResponseCode(response) + return (await response.json()) as meResponse } -export const postEmailLogin = async (email: string, password: string) => { - const response = await fetch(getBackendUrl() + "/auth/email", { - method: 'POST', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json' - }, - redirect: 'follow', - referrerPolicy: 'no-referrer', - body: JSON.stringify({ - email: email, - password: password, - }) - }); - - expectResponseCode(response); - return await response.json(); +export interface meResponse { + id: string + name: string + photo: string } -export const postLdapLogin = async (username: string, password: string) => { - const response = await fetch(getBackendUrl() + "/auth/ldap", { - method: 'POST', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json' - }, - redirect: 'follow', - referrerPolicy: 'no-referrer', - body: JSON.stringify({ - username: username, - password: password, - }) +export const postEmailLogin: ((email: string, password: string) => Promise) = async (email, password) => { + const response = await fetch(getBackendUrl() + '/auth/email', { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify({ + email: email, + password: password }) + }) - expectResponseCode(response) - return await response.json(); + expectResponseCode(response) } -export const postOpenIdLogin = async (openId: string) => { - const response = await fetch(getBackendUrl() + "/auth/openid", { - method: 'POST', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json' - }, - redirect: 'follow', - referrerPolicy: 'no-referrer', - body: JSON.stringify({ - openId: openId - }) +export const postLdapLogin: ((email: string, password: string) => Promise) = async (username, password) => { + const response = await fetch(getBackendUrl() + '/auth/ldap', { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify({ + username: username, + password: password }) + }) - expectResponseCode(response) - return await response.json(); + expectResponseCode(response) +} + +export const postOpenIdLogin: ((openid: string) => Promise) = async (openId: string) => { + const response = await fetch(getBackendUrl() + '/auth/openid', { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json' + }, + redirect: 'follow', + referrerPolicy: 'no-referrer', + body: JSON.stringify({ + openId: openId + }) + }) + + expectResponseCode(response) } diff --git a/src/components/application-loader/application-loader.tsx b/src/components/application-loader/application-loader.tsx index 36eec0913..a70deef6f 100644 --- a/src/components/application-loader/application-loader.tsx +++ b/src/components/application-loader/application-loader.tsx @@ -1,35 +1,35 @@ -import React, {Fragment, useEffect, useState} from "react"; -import "./application-loader.scss"; -import {LoadingScreen} from "./loading-screen"; +import React, { Fragment, useEffect, useState } from 'react' +import './application-loader.scss' +import { LoadingScreen } from './loading-screen' interface ApplicationLoaderProps { - initTasks: Promise[] + initTasks: Promise[] } -export const ApplicationLoader: React.FC = ({children, initTasks}) => { - const [failed, setFailed] = useState(false); - const [doneTasks, setDoneTasks] = useState(0); +export const ApplicationLoader: React.FC = ({ children, initTasks }) => { + const [failed, setFailed] = useState(false) + const [doneTasks, setDoneTasks] = useState(0) - useEffect(() => { - setDoneTasks(0); - initTasks.forEach(task => { - (async () => { - try { - await task; - setDoneTasks(prevDoneTasks => { - return prevDoneTasks + 1; - }) - } catch (reason) { - setFailed(true); - console.error(reason); - } - })(); - }) - }, [initTasks]); + const runTask:((task: Promise) => (Promise)) = async (task) => { + await task + setDoneTasks(prevDoneTasks => { + return prevDoneTasks + 1 + }) + } - return ( - doneTasks < initTasks.length || initTasks.length === 0 ? - : - {children} - ); -} \ No newline at end of file + useEffect(() => { + setDoneTasks(0) + for (const task of initTasks) { + runTask(task).catch(reason => { + setFailed(true) + console.error(reason) + }) + } + }, [initTasks]) + + return ( + doneTasks < initTasks.length || initTasks.length === 0 + ? + : {children} + ) +} diff --git a/src/components/application-loader/loading-screen.tsx b/src/components/application-loader/loading-screen.tsx index 57d06f8b3..99689d42e 100644 --- a/src/components/application-loader/loading-screen.tsx +++ b/src/components/application-loader/loading-screen.tsx @@ -1,21 +1,21 @@ -import React from "react"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {Alert} from "react-bootstrap"; +import React from 'react' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { Alert } from 'react-bootstrap' export interface LoadingScreenProps { - failed: boolean + failed: boolean } -export const LoadingScreen: React.FC = ({failed}) => { - return ( -
-
- -
- { - failed ? An error occured while loading the application! : null - } -
- ) -} \ No newline at end of file +export const LoadingScreen: React.FC = ({ failed }) => { + return ( +
+
+ +
+ { + failed ? An error occurred while loading the application! : null + } +
+ ) +} diff --git a/src/components/element-separator/element-separator.tsx b/src/components/element-separator/element-separator.tsx index 14d065d75..266ab8cd2 100644 --- a/src/components/element-separator/element-separator.tsx +++ b/src/components/element-separator/element-separator.tsx @@ -1,27 +1,27 @@ -import React, {Fragment} from "react"; +import React, { Fragment } from 'react' export interface ElementSeparatorProps { separator: React.ReactElement } -export const ElementSeparator: React.FC = ({children, separator}) => { - return ( - - { - React.Children - .toArray(children) - .filter(child => child !== null) - .map((child, index) => { - return ( - - { - (index > 0 ) ? separator : null - } - {child} - - ) - }) - } - - ) -} \ No newline at end of file +export const ElementSeparator: React.FC = ({ children, separator }) => { + return ( + + { + React.Children + .toArray(children) + .filter(child => child !== null) + .map((child, index) => { + return ( + + { + (index > 0) ? separator : null + } + {child} + + ) + }) + } + + ) +} diff --git a/src/components/icon-button/icon-button.tsx b/src/components/icon-button/icon-button.tsx index fde6e01f8..9ab31d827 100644 --- a/src/components/icon-button/icon-button.tsx +++ b/src/components/icon-button/icon-button.tsx @@ -1,24 +1,24 @@ -import React from "react"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import "./icon-button.scss"; -import {IconProp} from "@fortawesome/fontawesome-svg-core"; -import {Button, ButtonProps} from "react-bootstrap"; +import React from 'react' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import './icon-button.scss' +import { Button, ButtonProps } from 'react-bootstrap' +import { IconProp } from '../../utils/iconProp' export interface SocialButtonProps extends ButtonProps { - icon: IconProp - onClick?: () => void + icon: IconProp + onClick?: () => void } -export const IconButton: React.FC = ({icon, children, variant, onClick}) => { - return ( - - ) +export const IconButton: React.FC = ({ icon, children, variant, onClick }) => { + return ( + + ) } diff --git a/src/components/landing/layout/footer/external-link.tsx b/src/components/landing/layout/footer/external-link.tsx index 9c310b3dd..aefe62dc3 100644 --- a/src/components/landing/layout/footer/external-link.tsx +++ b/src/components/landing/layout/footer/external-link.tsx @@ -1,28 +1,27 @@ -import React, {Fragment} from "react"; -import {IconProp} from "@fortawesome/fontawesome-svg-core"; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import React, { Fragment } from 'react' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { IconProp } from '../../../../utils/iconProp' export interface ExternalLinkProp { - href: string; - text: string; - icon?: IconProp; + href: string; + text: string; + icon?: IconProp; } -export const ExternalLink: React.FC = ({href, text, icon}) => { - return ( - - { - icon ? - -   - - : - null - } - {text} - - ) +export const ExternalLink: React.FC = ({ href, text, icon }) => { + return ( + + { + icon + ? +   + + : null + } + {text} + + ) } diff --git a/src/components/landing/layout/footer/footer.tsx b/src/components/landing/layout/footer/footer.tsx index 864cb1a20..079155ec2 100644 --- a/src/components/landing/layout/footer/footer.tsx +++ b/src/components/landing/layout/footer/footer.tsx @@ -1,14 +1,14 @@ -import React from "react"; -import {LanguagePicker} from "./language-picker"; -import {PoweredByLinks} from "./powered-by-links"; -import {SocialLink} from "./social-links"; +import React from 'react' +import { LanguagePicker } from './language-picker' +import { PoweredByLinks } from './powered-by-links' +import { SocialLink } from './social-links' export const Footer: React.FC = () => { - return ( -
- - - -
- ); + return ( +
+ + + +
+ ) } diff --git a/src/components/landing/layout/footer/language-picker.tsx b/src/components/landing/layout/footer/language-picker.tsx index 74d69d4d7..6eaa6316f 100644 --- a/src/components/landing/layout/footer/language-picker.tsx +++ b/src/components/landing/layout/footer/language-picker.tsx @@ -1,54 +1,54 @@ -import React from "react"; -import {useTranslation} from "react-i18next"; -import moment from "moment"; -import { Form } from "react-bootstrap"; +import React from 'react' +import { useTranslation } from 'react-i18next' +import moment from 'moment' +import { Form } from 'react-bootstrap' const LanguagePicker: React.FC = () => { - const {i18n} = useTranslation(); + const { i18n } = useTranslation() - const onChangeLang = (event: React.ChangeEvent) => { - moment.locale(event.currentTarget.value); - i18n.changeLanguage(event.currentTarget.value); - } + const onChangeLang = async (event: React.ChangeEvent) => { + moment.locale(event.currentTarget.value) + await i18n.changeLanguage(event.currentTarget.value) + } - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) } export { LanguagePicker } diff --git a/src/components/landing/layout/footer/powered-by-links.tsx b/src/components/landing/layout/footer/powered-by-links.tsx index 07a48c9ad..05a414a4d 100644 --- a/src/components/landing/layout/footer/powered-by-links.tsx +++ b/src/components/landing/layout/footer/powered-by-links.tsx @@ -1,51 +1,35 @@ -import {Trans, useTranslation} from "react-i18next"; -import {TranslatedLink} from "./translated-link"; -import React, {Fragment} from "react"; -import {ExternalLink} from "./external-link"; -import {useSelector} from "react-redux"; -import {ApplicationState} from "../../../../redux"; +import { Trans, useTranslation } from 'react-i18next' +import { TranslatedLink } from './translated-link' +import React, { Fragment } from 'react' +import { ExternalLink } from './external-link' +import { useSelector } from 'react-redux' +import { ApplicationState } from '../../../../redux' -const PoweredByLinks: React.FC = () => { - useTranslation(); - const defaultLinks = [ - { - href: '/s/release-notes', - i18nKey: 'releases' - }, - { - href: 'https://github.com/codimd/server/tree/41b13e71b6b1d499238c04b15d65e3bd76442f1d', - i18nKey: 'sourceCode' - } - ] +export const PoweredByLinks: React.FC = () => { + useTranslation() - const config = useSelector((state: ApplicationState) => state.backendConfig); + const defaultLinks = + { + releases: '/s/release-notes', + sourceCode: 'https://github.com/codimd/server/tree/41b13e71b6b1d499238c04b15d65e3bd76442f1d' + } - const specialLinks = Object.entries(config.specialLinks) - .filter(([_, value]) => value !== "") - .map(([key, value]) => { - return { - href: value, - i18nKey: key - } - }) + const config = useSelector((state: ApplicationState) => state.backendConfig) - return ( -

- ]}/> - - { - (defaultLinks.concat(specialLinks)).map(({href, i18nKey}) => - -  |  - - - ) - } -

- ) + return ( +

+ ]}/> + { + Object.entries({ ...defaultLinks, ...(config.specialLinks) }).map(([i18nKey, href]) => + +  |  + + + ) + } +

+ ) } - -export { PoweredByLinks } diff --git a/src/components/landing/layout/footer/social-links.tsx b/src/components/landing/layout/footer/social-links.tsx index 5765a21d2..e7a4007d7 100644 --- a/src/components/landing/layout/footer/social-links.tsx +++ b/src/components/landing/layout/footer/social-links.tsx @@ -1,20 +1,20 @@ -import React from "react"; -import {Trans, useTranslation} from "react-i18next"; -import {ExternalLink} from "./external-link"; +import React from 'react' +import { Trans, useTranslation } from 'react-i18next' +import { ExternalLink } from './external-link' const SocialLink: React.FC = () => { - useTranslation(); - return ( -

- , - , - , - , - - ]}/> -

- ) + useTranslation() + return ( +

+ , + , + , + , + + ]}/> +

+ ) } export { SocialLink } diff --git a/src/components/landing/layout/footer/translated-link.tsx b/src/components/landing/layout/footer/translated-link.tsx index b4c703ab8..288b26ce1 100644 --- a/src/components/landing/layout/footer/translated-link.tsx +++ b/src/components/landing/layout/footer/translated-link.tsx @@ -1,21 +1,21 @@ -import React from "react"; -import {Trans, useTranslation} from "react-i18next"; +import React from 'react' +import { Trans, useTranslation } from 'react-i18next' export interface TranslatedLinkProps { - href: string; - i18nKey: string; + href: string; + i18nKey: string; } -const TranslatedLink: React.FC = ({href, i18nKey}) => { - useTranslation(); - return ( - - - - ) +const TranslatedLink: React.FC = ({ href, i18nKey }) => { + useTranslation() + return ( + + + + ) } -export {TranslatedLink} +export { TranslatedLink } diff --git a/src/components/landing/layout/index.tsx b/src/components/landing/layout/index.tsx index fb0eebb51..59337d057 100644 --- a/src/components/landing/layout/index.tsx +++ b/src/components/landing/layout/index.tsx @@ -1,30 +1,30 @@ -import React from "react"; -import {Redirect, Route, Switch} from "react-router-dom"; -import {History} from "../pages/history/history"; -import {Intro} from "../pages/intro/intro"; -import {Container} from "react-bootstrap"; -import {HeaderBar} from "./navigation/header-bar/header-bar"; -import {Footer} from "./footer/footer"; -import "./style/index.scss"; -import {Login} from "../pages/login/login"; +import React from 'react' +import { Redirect, Route, Switch } from 'react-router-dom' +import { History } from '../pages/history/history' +import { Intro } from '../pages/intro/intro' +import { Container } from 'react-bootstrap' +import { HeaderBar } from './navigation/header-bar/header-bar' +import { Footer } from './footer/footer' +import './style/index.scss' +import { Login } from '../pages/login/login' export const Landing: React.FC = () => { - return ( - - - - - - - - - - - - - - - -