Initial code commit
@@ -0,0 +1,448 @@
|
||||
# EditorConfig is awesome:http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# All Files
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers
|
||||
[*]
|
||||
# Don't use tabs for indentation.
|
||||
indent_style = space
|
||||
# (Please don't specify an indent_size here; that has too many unintended consequences.)
|
||||
|
||||
# Code files
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers
|
||||
[*.{cs,csx,vb,vbx}]
|
||||
charset = utf-8-bom
|
||||
end_of_line = crlf
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Solution Files
|
||||
[*.sln]
|
||||
indent_style = tab
|
||||
|
||||
# XML Project Files
|
||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||
indent_size = 2
|
||||
|
||||
# Configuration Files
|
||||
[*.{json,xml,yml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
|
||||
indent_size = 4
|
||||
|
||||
# Markdown Files
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
# Web Files
|
||||
[*.{htm,html,js,ts,css,scss,less}]
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
# Bash Files
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
|
||||
# Dotnet Code Style Settings
|
||||
# See https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers
|
||||
[*.{cs,csx,cake,vb}]
|
||||
dotnet_sort_system_directives_first = true
|
||||
dotnet_style_coalesce_expression = true:warning
|
||||
dotnet_style_collection_initializer = true:warning
|
||||
dotnet_style_explicit_tuple_names = true:warning
|
||||
dotnet_style_null_propagation = true:warning
|
||||
dotnet_style_object_initializer = true:warning
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
|
||||
dotnet_style_predefined_type_for_member_access = true:warning
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
|
||||
# Naming Symbols
|
||||
# constant_fields - Define constant fields
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
# non_private_readonly_fields - Define public, internal and protected readonly fields
|
||||
dotnet_naming_symbols.non_private_readonly_fields.applicable_accessibilities = public, internal, protected
|
||||
dotnet_naming_symbols.non_private_readonly_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.non_private_readonly_fields.required_modifiers = readonly
|
||||
# static_readonly_fields - Define static and readonly fields
|
||||
dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
|
||||
# private_readonly_fields - Define private readonly fields
|
||||
dotnet_naming_symbols.private_readonly_fields.applicable_accessibilities = private
|
||||
dotnet_naming_symbols.private_readonly_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_readonly_fields.required_modifiers = readonly
|
||||
# public_internal_fields - Define public and internal fields
|
||||
dotnet_naming_symbols.public_internal_fields.applicable_accessibilities = public, internal
|
||||
dotnet_naming_symbols.public_internal_fields.applicable_kinds = field
|
||||
# private_protected_fields - Define private and protected fields
|
||||
dotnet_naming_symbols.private_protected_fields.applicable_accessibilities = private, protected
|
||||
dotnet_naming_symbols.private_protected_fields.applicable_kinds = field
|
||||
# public_symbols - Define any public symbol
|
||||
dotnet_naming_symbols.public_symbols.applicable_accessibilities = public, internal, protected, protected_internal
|
||||
dotnet_naming_symbols.public_symbols.applicable_kinds = method, property, event, delegate
|
||||
# parameters - Defines any parameter
|
||||
dotnet_naming_symbols.parameters.applicable_kinds = parameter
|
||||
# non_interface_types - Defines class, struct, enum and delegate types
|
||||
dotnet_naming_symbols.non_interface_types.applicable_kinds = class, struct, enum, delegate
|
||||
# interface_types - Defines interfaces
|
||||
dotnet_naming_symbols.interface_types.applicable_kinds = interface
|
||||
|
||||
# Naming Styles
|
||||
# camel_case - Define the camelCase style
|
||||
dotnet_naming_style.camel_case.capitalization = camel_case
|
||||
# pascal_case - Define the Pascal_case style
|
||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||
# first_upper - The first character must start with an upper-case character
|
||||
dotnet_naming_style.first_upper.capitalization = first_word_upper
|
||||
# prefix_interface_interface_with_i - Interfaces must be PascalCase and the first character of an interface must be an 'I'
|
||||
dotnet_naming_style.prefix_interface_interface_with_i.capitalization = pascal_case
|
||||
dotnet_naming_style.prefix_interface_interface_with_i.required_prefix = I
|
||||
|
||||
# Naming Rules
|
||||
# Constant fields must be PascalCase
|
||||
dotnet_naming_rule.constant_fields_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.constant_fields_must_be_pascal_case.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields_must_be_pascal_case.style = pascal_case
|
||||
# Public, internal and protected readonly fields must be PascalCase
|
||||
dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.symbols = non_private_readonly_fields
|
||||
dotnet_naming_rule.non_private_readonly_fields_must_be_pascal_case.style = pascal_case
|
||||
# Static readonly fields must be PascalCase
|
||||
dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.symbols = static_readonly_fields
|
||||
dotnet_naming_rule.static_readonly_fields_must_be_pascal_case.style = pascal_case
|
||||
# Private readonly fields must be camelCase
|
||||
dotnet_naming_rule.private_readonly_fields_must_be_camel_case.severity = warning
|
||||
dotnet_naming_rule.private_readonly_fields_must_be_camel_case.symbols = private_readonly_fields
|
||||
dotnet_naming_rule.private_readonly_fields_must_be_camel_case.style = camel_case
|
||||
# Public and internal fields must be PascalCase
|
||||
dotnet_naming_rule.public_internal_fields_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.public_internal_fields_must_be_pascal_case.symbols = public_internal_fields
|
||||
dotnet_naming_rule.public_internal_fields_must_be_pascal_case.style = pascal_case
|
||||
# Private and protected fields must be camelCase
|
||||
dotnet_naming_rule.private_protected_fields_must_be_camel_case.severity = warning
|
||||
dotnet_naming_rule.private_protected_fields_must_be_camel_case.symbols = private_protected_fields
|
||||
dotnet_naming_rule.private_protected_fields_must_be_camel_case.style = camel_case
|
||||
# Public members must be capitalized
|
||||
dotnet_naming_rule.public_members_must_be_capitalized.severity = warning
|
||||
dotnet_naming_rule.public_members_must_be_capitalized.symbols = public_symbols
|
||||
dotnet_naming_rule.public_members_must_be_capitalized.style = first_upper
|
||||
# Parameters must be camelCase
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.severity = warning
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.symbols = parameters
|
||||
dotnet_naming_rule.parameters_must_be_camel_case.style = camel_case
|
||||
# Class, struct, enum and delegates must be PascalCase
|
||||
dotnet_naming_rule.non_interface_types_must_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.non_interface_types_must_be_pascal_case.symbols = non_interface_types
|
||||
dotnet_naming_rule.non_interface_types_must_be_pascal_case.style = pascal_case
|
||||
# Interfaces must be PascalCase and start with an 'I'
|
||||
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.severity = warning
|
||||
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.symbols = interface_types
|
||||
dotnet_naming_rule.interface_types_must_be_prefixed_with_i.style = prefix_interface_interface_with_i
|
||||
|
||||
# C# Code Style Settings
|
||||
# See https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers
|
||||
[*.{cs,csx,cake}]
|
||||
|
||||
# Indentation Preferences
|
||||
# http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_indent_block_contents
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# New Line Preferences
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_new_line_before_catch
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
csharp_prefer_braces = true:suggestion
|
||||
csharp_prefer_simple_default_expression = true:warning
|
||||
|
||||
# Wrapping Preferences
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_preserve_single_line_blocks
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = false
|
||||
|
||||
# Spacing Preferences
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_space_after_cast
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = do_not_ignore
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = none
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# CSharp Style Preferences
|
||||
# See http://kent-boogaart.com/blog/editorconfig-reference-for-c-developers#csharp_style_conditional_delegate_call
|
||||
csharp_style_conditional_delegate_call = true:warning
|
||||
csharp_style_expression_bodied_accessors = true:warning
|
||||
csharp_style_expression_bodied_constructors = false:warning
|
||||
csharp_style_expression_bodied_indexers = true:warning
|
||||
csharp_style_expression_bodied_methods = false:warning
|
||||
csharp_style_expression_bodied_operators =false:warning
|
||||
csharp_style_expression_bodied_properties = true:warning
|
||||
csharp_style_inlined_variable_declaration = true:warning
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:warning
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
|
||||
csharp_style_throw_expression = true:warning
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
csharp_style_var_for_built_in_types = true:none
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
|
||||
# Resharper preferences
|
||||
# See https://www.jetbrains.com/help/rider/EditorConfig_Properties.html
|
||||
csharp_keep_blank_lines_in_declarations = 1
|
||||
csharp_remove_blank_lines_near_braces_in_declarations = true
|
||||
csharp_keep_blank_lines_in_code = 1
|
||||
csharp_remove_blank_lines_near_braces_in_code = true
|
||||
csharp_blank_lines_around_namespace = 1
|
||||
csharp_blank_lines_inside_namespace = 0
|
||||
csharp_blank_lines_around_type = 1
|
||||
csharp_blank_lines_inside_type = 0
|
||||
csharp_blank_lines_around_field = 0
|
||||
csharp_blank_lines_around_single_line_field = 0
|
||||
csharp_blank_lines_around_property = 1
|
||||
csharp_blank_lines_around_single_line_property = 1
|
||||
csharp_blank_lines_around_auto_property = 1
|
||||
csharp_blank_lines_around_single_line_auto_property = 1
|
||||
csharp_blank_lines_around_invocable = 1
|
||||
csharp_blank_lines_around_single_line_invocable = 1
|
||||
csharp_blank_lines_around_local_method = 1
|
||||
csharp_blank_lines_around_single_line_local_method = 1
|
||||
csharp_blank_lines_around_region = 1
|
||||
csharp_blank_lines_inside_region = 1
|
||||
csharp_blank_lines_between_using_groups = 0
|
||||
csharp_blank_lines_after_using_list = 1
|
||||
csharp_blank_lines_after_start_comment = 1
|
||||
csharp_blank_lines_before_single_line_comment = 1
|
||||
csharp_blank_lines_after_control_transfer_statements = 1
|
||||
|
||||
csharp_type_declaration_braces = next_line
|
||||
csharp_invocable_declaration_braces = next_line
|
||||
csharp_anonymous_method_declaration_braces = next_line
|
||||
csharp_accessor_owner_declaration_braces = next_line
|
||||
csharp_accessor_declaration_braces = next_line
|
||||
csharp_case_block_braces = next_line
|
||||
csharp_initializer_braces = next_line
|
||||
csharp_other_braces = next_line
|
||||
csharp_empty_block_style = multiline
|
||||
|
||||
csharp_indent_style = space
|
||||
csharp_indent_size = 4
|
||||
csharp_tab_width = 4
|
||||
|
||||
csharp_keep_user_linebreaks = false
|
||||
csharp_simple_embedded_statement_style = line_break
|
||||
csharp_simple_case_statement_style = line_break
|
||||
csharp_simple_embedded_block_style = line_break
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_while = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
|
||||
|
||||
csharp_max_line_length = 160
|
||||
csharp_wrap_parameters_style = chop_if_long
|
||||
csharp_wrap_before_declaration_lpar = false
|
||||
csharp_wrap_after_declaration_lpar = true
|
||||
csharp_wrap_arguments_style = chop_if_long
|
||||
csharp_wrap_before_invocation_lpar = false
|
||||
csharp_wrap_after_invocation_lpar = true
|
||||
csharp_wrap_before_comma = false
|
||||
csharp_wrap_before_arrow_with_expressions = false
|
||||
csharp_wrap_after_dot_in_method_calls = false
|
||||
csharp_wrap_chained_method_calls = chop_if_long
|
||||
csharp_wrap_before_extends_colon = false
|
||||
csharp_wrap_extends_list_style = chop_if_long
|
||||
csharp_wrap_for_stmt_header_style = chop_if_long
|
||||
csharp_wrap_before_ternary_opsigns = true
|
||||
csharp_wrap_ternary_expr_style = chop_if_long
|
||||
csharp_wrap_multiple_declaration_style = wrap_if_long
|
||||
csharp_wrap_linq_expressions = chop_if_long
|
||||
csharp_wrap_before_binary_opsign = false
|
||||
csharp_wrap_chained_binary_expressions = chop_if_long
|
||||
csharp_force_chop_compound_if_expression = false
|
||||
csharp_force_chop_compound_while_expression = false
|
||||
csharp_force_chop_compound_do_expression = false
|
||||
csharp_wrap_multiple_type_parameter_constraints_style = chop_always
|
||||
csharp_wrap_object_and_collection_initializer_style = chop_always
|
||||
csharp_wrap_array_initializer_style = chop_always
|
||||
csharp_wrap_before_first_type_parameter_constraint = false
|
||||
csharp_wrap_before_type_parameter_langle = false
|
||||
csharp_place_abstract_accessorholder_on_single_line = true
|
||||
csharp_place_simple_accessorholder_on_single_line = false
|
||||
csharp_place_accessor_with_attrs_holder_on_single_line = false
|
||||
csharp_place_simple_accessor_on_single_line = true
|
||||
csharp_place_simple_method_on_single_line = false
|
||||
csharp_place_simple_anonymousmethod_on_single_line = false
|
||||
csharp_place_simple_initializer_on_single_line = true
|
||||
csharp_place_type_attribute_on_same_line = false
|
||||
csharp_place_method_attribute_on_same_line = false
|
||||
csharp_place_accessorholder_attribute_on_same_line = false
|
||||
csharp_place_simple_accessor_attribute_on_same_line = false
|
||||
csharp_place_complex_accessor_attribute_on_same_line = false
|
||||
csharp_place_field_attribute_on_same_line = false
|
||||
csharp_place_constructor_initializer_on_same_line = false
|
||||
csharp_place_type_constraints_on_same_line = false
|
||||
csharp_allow_comment_after_lbrace = false
|
||||
csharp_continuous_indent_multiplier = false
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_nested_usings_stmt = true
|
||||
csharp_indent_nested_fixed_stmt = true
|
||||
csharp_indent_nested_lock_stmt = true
|
||||
csharp_indent_nested_for_stmt = true
|
||||
csharp_indent_nested_foreach_stmt = true
|
||||
csharp_indent_nested_while_stmt = true
|
||||
csharp_indent_type_constraints = true
|
||||
csharp_stick_comment = false
|
||||
csharp_indent_method_decl_pars = inside
|
||||
csharp_indent_invocation_pars = inside
|
||||
csharp_indent_statement_pars = inside
|
||||
csharp_indent_typeparam_angles = inside
|
||||
csharp_indent_typearg_angles = inside
|
||||
csharp_indent_pars = inside
|
||||
csharp_align_multiline_parameter = false
|
||||
csharp_align_first_arg_by_paren = false
|
||||
csharp_align_multiline_argument = false
|
||||
csharp_align_multiline_extends_list = false
|
||||
csharp_align_multiline_expression = false
|
||||
csharp_align_multiline_binary_expressions_chain = false
|
||||
csharp_align_multiline_calls_chain = false
|
||||
csharp_align_multiline_array_and_object_initializer = false
|
||||
csharp_indent_anonymous_method_block = false
|
||||
csharp_align_multiline_for_stmt = false
|
||||
csharp_align_multiple_declaration = false
|
||||
csharp_align_multline_type_parameter_list = false
|
||||
csharp_align_multline_type_parameter_constrains = false
|
||||
csharp_align_linq_query = false
|
||||
csharp_special_else_if_treatment = true
|
||||
csharp_insert_final_newline = false
|
||||
csharp_old_engine = false
|
||||
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_before_typeof_parentheses = false
|
||||
csharp_space_before_default_parentheses = false
|
||||
csharp_space_before_checked_parentheses = false
|
||||
csharp_space_before_sizeof_parentheses = false
|
||||
csharp_space_before_nameof_parentheses = false
|
||||
csharp_space_before_type_parameter_angle = false
|
||||
csharp_space_before_type_argument_angle = false
|
||||
csharp_space_around_binary_operator = true
|
||||
csharp_space_around_member_access_operator = false
|
||||
csharp_space_after_logical_not_op = false
|
||||
csharp_space_after_unary_minus_op = false
|
||||
csharp_space_after_unary_plus_op = false
|
||||
csharp_space_after_ampersand_op = false
|
||||
csharp_space_after_asterik_op = false
|
||||
csharp_space_within_parentheses = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
csharp_space_between_typecast_parentheses = false
|
||||
space_between_parentheses_of_control_flow_statements = false
|
||||
csharp_space_within_typeof_parentheses = false
|
||||
csharp_space_within_default_parentheses = false
|
||||
csharp_space_within_checked_parentheses = false
|
||||
csharp_space_within_sizeof_parentheses = false
|
||||
csharp_space_within_nameof_parentheses = false
|
||||
csharp_space_within_type_parameter_angles = false
|
||||
csharp_space_within_type_argument_angles = false
|
||||
csharp_space_before_ternary_quest = true
|
||||
csharp_space_after_ternary_quest = true
|
||||
csharp_space_before_ternary_colon = true
|
||||
csharp_space_after_ternary_colon = true
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_near_postfix_and_prefix_op = false
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_before_attribute_colon = false
|
||||
csharp_space_after_attribute_colon = true
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_around_dot = false
|
||||
csharp_space_around_lambda_arrow = true
|
||||
csharp_space_before_singleline_accessorholder = true
|
||||
csharp_space_in_singleline_accessorholder = true
|
||||
csharp_space_between_accessors_in_singleline_property = true
|
||||
csharp_space_between_attribute_sections = false
|
||||
csharp_space_withing_empty_braces = true
|
||||
csharp_space_in_singleline_method = true
|
||||
csharp_space_in_singleline_anonymous_method = true
|
||||
csharp_space_between_square_brackets = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_between_square_brackets = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_within_single_line_array_initializer_braces = true
|
||||
csharp_space_before_pointer_asterik_declaration = false
|
||||
csharp_space_before_semicolon = false
|
||||
csharp_space_before_colon_in_case = false
|
||||
csharp_space_before_nullable_mark = false
|
||||
csharp_space_before_type_parameter_constraint_colon = true
|
||||
csharp_space_after_type_parameter_constraint_colon = true
|
||||
csharp_space_around_alias_eq = true
|
||||
csharp_space_before_trailing_comment = true
|
||||
csharp_space_after_operator_keyword = true
|
||||
|
||||
xmldoc_wrap_tags_and_pi = false
|
||||
xmldoc_spaces_around_eq_in_pi_attribute = false
|
||||
xmldoc_space_after_last_pi_attribute = false
|
||||
xmldoc_pi_attribute_style = on_single_line
|
||||
xmldoc_pi_attributes_indent = single_indent
|
||||
xmldoc_blank_line_after_pi = false
|
||||
xmldoc_spaces_around_eq_in_attribute = false
|
||||
xmldoc_space_after_last_attribute = false
|
||||
xmldoc_space_before_self_closing = false
|
||||
xmldoc_attribute_style = on_single_line
|
||||
xmldoc_attribute_indent = single_indent
|
||||
xmldoc_keep_user_linebreaks = false
|
||||
xmldoc_linebreaks_inside_tags_for_multiline_elements = true
|
||||
xmldoc_linebreaks_inside_tags_for_elements_with_child_elements = true
|
||||
xmldoc_linebreaks_inside_tags_for_elements_longer_than = 0
|
||||
xmldoc_spaces_inside_tags = 1
|
||||
xmldoc_wrap_text = false
|
||||
xmldoc_wrap_around_elements = true
|
||||
xmldoc_indent_child_elements = zeroindent
|
||||
xmldoc_indent_text = zeroident
|
||||
xmldoc_max_blank_lines_between_tags = 0
|
||||
xmldoc_linebreak_before_multiline_elements = true
|
||||
xmldoc_linebreak_before_singleline_elements = false
|
||||
|
||||
csharp_trailing_comma_in_multiline_lists = true
|
||||
@@ -0,0 +1,388 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Nuget personal access tokens and Credentials
|
||||
nuget.config
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{3DE3C789-92CE-4A02-B44D-F724A6D6989E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A480F303-D539-43CE-A292-34C922224742}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Core", "core\Rsdo.Concordancer.Core\Rsdo.Concordancer.Core.csproj", "{35EAFDA5-0F81-46BF-9A39-6F86A0761D90}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.ServiceModel", "core\Rsdo.Concordancer.ServiceModel\Rsdo.Concordancer.ServiceModel.csproj", "{1D5E751F-D7DF-445E-A583-01678242AB45}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Services", "core\Rsdo.Concordancer.Services\Rsdo.Concordancer.Services.csproj", "{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Infrastructure", "core\Rsdo.Concordancer.Infrastructure\Rsdo.Concordancer.Infrastructure.csproj", "{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Tests.Unit", "tests\Rsdo.Concordancer.Tests.Unit\Rsdo.Concordancer.Tests.Unit.csproj", "{50321513-0564-469B-9160-DEA7430F2FFB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Tests.Integration", "tests\Rsdo.Concordancer.Tests.Integration\Rsdo.Concordancer.Tests.Integration.csproj", "{EE998A04-3E65-493A-8C70-C830063A0871}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Api", "apps\Rsdo.Concordancer.Api\Rsdo.Concordancer.Api.csproj", "{D1204EBA-6D8B-433E-8778-F240D1D5B11A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.Data", "core\Rsdo.Concordancer.Data\Rsdo.Concordancer.Data.csproj", "{EDBA6BA0-CCCB-4678-A675-539DD795E063}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rsdo.Concordancer.SystemManager", "apps\Rsdo.Concordancer.SystemManager\Rsdo.Concordancer.SystemManager.csproj", "{41B26AD1-C0A5-4796-95D0-CB84FB574A83}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{35EAFDA5-0F81-46BF-9A39-6F86A0761D90} = {8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}
|
||||
{1D5E751F-D7DF-445E-A583-01678242AB45} = {8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}
|
||||
{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1} = {8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}
|
||||
{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC} = {8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}
|
||||
{50321513-0564-469B-9160-DEA7430F2FFB} = {A480F303-D539-43CE-A292-34C922224742}
|
||||
{EE998A04-3E65-493A-8C70-C830063A0871} = {A480F303-D539-43CE-A292-34C922224742}
|
||||
{D1204EBA-6D8B-433E-8778-F240D1D5B11A} = {3DE3C789-92CE-4A02-B44D-F724A6D6989E}
|
||||
{EDBA6BA0-CCCB-4678-A675-539DD795E063} = {8DB3C9A5-C6CF-4006-ACDA-14AF9A336EE2}
|
||||
{41B26AD1-C0A5-4796-95D0-CB84FB574A83} = {3DE3C789-92CE-4A02-B44D-F724A6D6989E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{35EAFDA5-0F81-46BF-9A39-6F86A0761D90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{35EAFDA5-0F81-46BF-9A39-6F86A0761D90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{35EAFDA5-0F81-46BF-9A39-6F86A0761D90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{35EAFDA5-0F81-46BF-9A39-6F86A0761D90}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1D5E751F-D7DF-445E-A583-01678242AB45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1D5E751F-D7DF-445E-A583-01678242AB45}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D5E751F-D7DF-445E-A583-01678242AB45}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1D5E751F-D7DF-445E-A583-01678242AB45}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5C46DF9-C8B9-41EE-9874-19713CDAAFB1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6711EF5-DDDE-4AA8-B17C-449CBE4B0DAC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{50321513-0564-469B-9160-DEA7430F2FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{50321513-0564-469B-9160-DEA7430F2FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{50321513-0564-469B-9160-DEA7430F2FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{50321513-0564-469B-9160-DEA7430F2FFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE998A04-3E65-493A-8C70-C830063A0871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE998A04-3E65-493A-8C70-C830063A0871}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE998A04-3E65-493A-8C70-C830063A0871}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE998A04-3E65-493A-8C70-C830063A0871}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1204EBA-6D8B-433E-8778-F240D1D5B11A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1204EBA-6D8B-433E-8778-F240D1D5B11A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1204EBA-6D8B-433E-8778-F240D1D5B11A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1204EBA-6D8B-433E-8778-F240D1D5B11A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EDBA6BA0-CCCB-4678-A675-539DD795E063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EDBA6BA0-CCCB-4678-A675-539DD795E063}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EDBA6BA0-CCCB-4678-A675-539DD795E063}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EDBA6BA0-CCCB-4678-A675-539DD795E063}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{41B26AD1-C0A5-4796-95D0-CB84FB574A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{41B26AD1-C0A5-4796-95D0-CB84FB574A83}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{41B26AD1-C0A5-4796-95D0-CB84FB574A83}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{41B26AD1-C0A5-4796-95D0-CB84FB574A83}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,357 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/Browsers/Browsers/@EntryValue">C65+,E16+,FF58+,IE11+</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/AnalysisEnabled/@EntryValue">VISIBLE_FILES</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ArrangeThisQualifier/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CSharpWarnings_003A_003ACS1591/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Reformat_0020Code_0020IDE/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Reformat Code IDE"><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="False" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="False" ArrangeCodeBodyStyle="False" /><CSArrangeQualifiers>True</CSArrangeQualifiers><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CSShortenReferences>True</CSShortenReferences><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags></Profile></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=StyleCop/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="StyleCop"><CSUpdateFileHeader>False</CSUpdateFileHeader><CSArrangeQualifiers>True</CSArrangeQualifiers><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers></Profile></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">None</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||
<TypePattern DisplayName="Non-reorderable types">
|
||||
<TypePattern.Match>
|
||||
<Or>
|
||||
<And>
|
||||
<Kind Is="Interface" />
|
||||
<Or>
|
||||
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
|
||||
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
|
||||
</Or>
|
||||
</And>
|
||||
<Kind Is="Struct" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorder" />
|
||||
</Or>
|
||||
</TypePattern.Match>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasMember>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
|
||||
</And>
|
||||
</HasMember>
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constructor" />
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<ImplementsInterface Name="System.IDisposable" />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Kind Order="Constructor" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Test Methods" Priority="100">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<Or>
|
||||
<HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
|
||||
</Or>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Test Methods" Priority="100">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="NUnit.Framework.TestAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="Default Pattern (StyleCop)" RemoveRegions="All">
|
||||
<Entry DisplayName="Constants">
|
||||
<Entry.Match>
|
||||
<Kind Is="Constant" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Static fields">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Field" />
|
||||
<Static />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Fields">
|
||||
<Entry.Match>
|
||||
<Kind Is="Field" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Constructors and Destructors" Priority="200">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constructor" />
|
||||
<Kind Is="Destructor" />
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Kind Order="Constructor Destructor" />
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Delegates">
|
||||
<Entry.Match>
|
||||
<Kind Is="Delegate" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Public events">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Event" />
|
||||
<Access Is="Public" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interface events">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Event" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<ImplementsInterface Immediate="True" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Other events">
|
||||
<Entry.Match>
|
||||
<Kind Is="Event" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Enums">
|
||||
<Entry.Match>
|
||||
<Kind Is="Enum" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interfaces">
|
||||
<Entry.Match>
|
||||
<Kind Is="Interface" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Public properties">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Property" />
|
||||
<Access Is="Public" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interface properties">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Property" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<ImplementsInterface Immediate="True" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Other properties">
|
||||
<Entry.Match>
|
||||
<Kind Is="Property" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Public indexers" Priority="1000">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Indexer" />
|
||||
<Access Is="Public" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interface indexers" Priority="1000">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Indexer" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<ImplementsInterface Immediate="True" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Other indexers" Priority="1000">
|
||||
<Entry.Match>
|
||||
<Kind Is="Indexer" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Public methods and operators">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Or>
|
||||
<Kind Is="Method" />
|
||||
<Kind Is="Operator" />
|
||||
</Or>
|
||||
<Access Is="Public" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Interface methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<ImplementsInterface />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<ImplementsInterface Immediate="True" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Other methods">
|
||||
<Entry.Match>
|
||||
<Kind Is="Method" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Operators">
|
||||
<Entry.Match>
|
||||
<Kind Is="Operator" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Nested structs" Priority="600">
|
||||
<Entry.Match>
|
||||
<Kind Is="Struct" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Nested classes" Priority="700">
|
||||
<Entry.Match>
|
||||
<Kind Is="Class" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Access Order="Public Internal ProtectedInternal Protected Private" />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
</TypePattern>
|
||||
</Patterns></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpUsing/KeepImports/=System/@EntryIndexedValue">System</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpUsing/KeepImports/=System_002ELinq/@EntryIndexedValue">System.Linq</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MB/@EntryIndexedValue">MB</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Dtos/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -0,0 +1,25 @@
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/.idea
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
@@ -0,0 +1 @@
|
||||
log*.txt
|
||||
@@ -0,0 +1,15 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
public abstract class BaseController : ControllerBase
|
||||
{
|
||||
protected BaseController(IMediator mediator)
|
||||
{
|
||||
Mediator = mediator;
|
||||
}
|
||||
|
||||
protected IMediator Mediator { get; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Concordancer;
|
||||
|
||||
[ApiExplorerSettings(GroupName = ServiceApiInfo.ApiGroupConcordancer)]
|
||||
[Route(ServiceApiInfo.ApiGroupConcordancer + "/corpus/{corpusId:guid}")]
|
||||
public abstract class BaseConcordancerController : BaseController
|
||||
{
|
||||
protected BaseConcordancerController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.Concordances;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Concordancer;
|
||||
|
||||
public class ConcordancesController : BaseConcordancerController
|
||||
{
|
||||
public ConcordancesController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpPost("concordances/details")]
|
||||
public async Task<ConcordanceDetailsResponse> Details(Guid corpusId, ConcordanceDetails request)
|
||||
{
|
||||
request.CorpusId = corpusId;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost("concordances/search")]
|
||||
public async Task<SearchConcordancesResponse> Search(Guid corpusId, SearchConcordances request)
|
||||
{
|
||||
request.CorpusId = corpusId;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost("concordances/export")]
|
||||
public async Task<IActionResult> Export(Guid corpusId, ExportConcordances request)
|
||||
{
|
||||
request.CorpusId = corpusId;
|
||||
var response = await Mediator.Send(request);
|
||||
return File(response.Stream, response.ContentType, response.FileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.Corpuses;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Concordancer;
|
||||
|
||||
public class CorpusController : BaseConcordancerController
|
||||
{
|
||||
public CorpusController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("stats")]
|
||||
public async Task<GetCorpusStatisticsResponse> Statistics(Guid corpusId)
|
||||
{
|
||||
var request = new GetCorpusStatistics()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.TermLists;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Concordancer;
|
||||
|
||||
public class ListController : BaseConcordancerController
|
||||
{
|
||||
public ListController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpPost("list/search")]
|
||||
public async Task<SearchTermListResponse> Search(Guid corpusId, SearchTermList request)
|
||||
{
|
||||
request.CorpusId = corpusId;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost("list/export")]
|
||||
public async Task<IActionResult> Export(Guid corpusId, ExportTermList request)
|
||||
{
|
||||
request.CorpusId = corpusId;
|
||||
var response = await Mediator.Send(request);
|
||||
return File(response.Stream, response.ContentType, response.FileName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Dashboard;
|
||||
|
||||
[ApiExplorerSettings(GroupName = ServiceApiInfo.ApiGroupDashboard)]
|
||||
[Route(ServiceApiInfo.ApiGroupDashboard + "/corpus")]
|
||||
public abstract class BaseDashboardController : BaseController
|
||||
{
|
||||
protected BaseDashboardController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.Corpuses;
|
||||
using Rsdo.Concordancer.ServiceModel.Shared;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Dashboard;
|
||||
|
||||
public class CorpusController : BaseDashboardController
|
||||
{
|
||||
public CorpusController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("{corpusId:guid}")]
|
||||
[SwaggerOperation("Returns information about corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Information about corpus", typeof(GetCorpusResponse), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Corpus was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<GetCorpusResponse> Get([SwaggerParameter("Corpus id", Required = true)] Guid corpusId)
|
||||
{
|
||||
var request = new GetCorpus()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[SwaggerOperation("Creates new corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.Created, "Corpus was created", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Create([SwaggerParameter("Corpus information", Required = true)] CreateCorpus request)
|
||||
{
|
||||
Response.StatusCode = (int)HttpStatusCode.Created;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpDelete("{corpusId:guid}")]
|
||||
[SwaggerOperation("Deletes corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Corpus was deleted", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Corpus was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Delete([SwaggerParameter("Corpus id", Required = true)] Guid corpusId)
|
||||
{
|
||||
var request = new DeleteCorpus()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.TermLists;
|
||||
using Rsdo.Concordancer.ServiceModel.Shared;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Dashboard;
|
||||
|
||||
public class TermListController : BaseDashboardController
|
||||
{
|
||||
public TermListController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("{corpusId:guid}/termList/{termListId:guid}")]
|
||||
[SwaggerOperation("Returns information about term list")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Information about term list", typeof(GetTermListResponse), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Term list was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<GetTermListResponse> Get(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Term list id", Required = true)] Guid termListId)
|
||||
{
|
||||
var request = new GetTermList()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
TermListId = termListId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost("{corpusId:guid}/termList")]
|
||||
[SwaggerOperation("Creates term list in selected corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.Created, "Corpus was created", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Create(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Term list information", Required = true)] CreateTermList request)
|
||||
{
|
||||
Response.StatusCode = (int)HttpStatusCode.Created;
|
||||
request.CorpusId = corpusId;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpDelete("{corpusId:guid}/termList/{termListId:guid}")]
|
||||
[SwaggerOperation("Deletes term list from selected corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Term list was deleted", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Term list was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Delete(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Term list id", Required = true)] Guid termListId)
|
||||
{
|
||||
var request = new DeleteTermList()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
TermListId = termListId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Rsdo.Concordancer.Core.Interfaces;
|
||||
using Rsdo.Concordancer.ServiceModel.Requests.Texts;
|
||||
using Rsdo.Concordancer.ServiceModel.Shared;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers.Dashboard;
|
||||
|
||||
public class TextController : BaseDashboardController
|
||||
{
|
||||
public TextController(IMediator mediator)
|
||||
: base(mediator)
|
||||
{
|
||||
}
|
||||
|
||||
[HttpGet("{corpusId:guid}/text/{textId:guid}")]
|
||||
[SwaggerOperation("Returns information about text")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Information about text", typeof(GetTextResponse), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Text was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<GetTextResponse> Get(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Text id", Required = true)] Guid textId)
|
||||
{
|
||||
var request = new GetText()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
TextId = textId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpPost("{corpusId:guid}/text")]
|
||||
[SwaggerOperation("Creates text in selected corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.Created, "Text was created", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Create(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Text information", Required = true)] CreateText request)
|
||||
{
|
||||
Response.StatusCode = (int)HttpStatusCode.Created;
|
||||
request.CorpusId = corpusId;
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
|
||||
[HttpDelete("{corpusId:guid}/text/{textId:guid}")]
|
||||
[SwaggerOperation("Deletes text from selected corpus")]
|
||||
[SwaggerResponse((int)HttpStatusCode.OK, "Text was deleted", typeof(ExecutionResult), MediaTypeNames.Application.Json)]
|
||||
[SwaggerResponse((int)HttpStatusCode.NotFound, "Text was not found")]
|
||||
[SwaggerResponse((int)HttpStatusCode.InternalServerError, "Internal server error")]
|
||||
public async Task<ExecutionResult> Delete(
|
||||
[SwaggerParameter("Corpus id", Required = true)] Guid corpusId,
|
||||
[SwaggerParameter("Text id", Required = true)] Guid textId)
|
||||
{
|
||||
var request = new DeleteText()
|
||||
{
|
||||
CorpusId = corpusId,
|
||||
TextId = textId,
|
||||
};
|
||||
return await Mediator.Send(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers;
|
||||
|
||||
public static class ServiceApiInfo
|
||||
{
|
||||
public const string ServiceName = "RSDO";
|
||||
public const string ApiGroupConcordancer = "concordancer";
|
||||
public const string ApiGroupDashboard = "dashboard";
|
||||
|
||||
public static Version ServiceVersion => typeof(ServiceApiInfo).Assembly.GetName().Version;
|
||||
|
||||
public static OpenApiInfo GetOpenApiInfo()
|
||||
{
|
||||
return new OpenApiInfo()
|
||||
{
|
||||
Title = $"{ServiceName} API",
|
||||
Version = ServiceVersion.ToString(3),
|
||||
Contact = new OpenApiContact()
|
||||
{
|
||||
Name = "Amebis, d. o. o., Kamnik",
|
||||
Email = "info@amebis.si",
|
||||
Url = new Uri("https://amebis.si"),
|
||||
},
|
||||
Description = $"API which is used in a concordancer developed in the project RSDO (Razvoj slovenščine v digitalnem okolju).",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using HtmlAgilityPack;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Rsdo.Concordancer.Core.Constants;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Controllers
|
||||
{
|
||||
public class WebAppController : Controller
|
||||
{
|
||||
private readonly IConfiguration configuration;
|
||||
private readonly IWebHostEnvironment webHostEnvironment;
|
||||
|
||||
public WebAppController(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.webHostEnvironment = webHostEnvironment;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
var indexFilePath = webHostEnvironment.WebRootFileProvider.GetFileInfo("index.html").PhysicalPath;
|
||||
var html = new HtmlDocument();
|
||||
html.Load(indexFilePath);
|
||||
|
||||
var baseAppPath = configuration[ConfigurationKey.Web.BaseAppPath] ?? string.Empty;
|
||||
var scriptNode = HtmlNode.CreateNode($"<script>window.baseAppPath = '{baseAppPath}';</script>");
|
||||
var headNode = html.DocumentNode.SelectSingleNode("//head");
|
||||
headNode.ChildNodes.Add(scriptNode);
|
||||
|
||||
var indexStream = new MemoryStream();
|
||||
html.Save(indexStream);
|
||||
indexStream.Position = 0;
|
||||
|
||||
return File(indexStream, MediaTypeNames.Text.Html);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
|
||||
# COPY LOCAL NUGET PACKAGES
|
||||
WORKDIR /nuget
|
||||
COPY local-packages/. .
|
||||
|
||||
# ADD LOCAL NUGET SOURCE
|
||||
RUN dotnet nuget add source /nuget
|
||||
|
||||
# RESTORE PACKAGES (with project files only)
|
||||
WORKDIR /src/apps
|
||||
COPY src/apps/Rsdo.Concordancer.Api/Rsdo.Concordancer.Api.csproj Rsdo.Concordancer.Api/Rsdo.Concordancer.Api.csproj
|
||||
|
||||
WORKDIR /src/core
|
||||
COPY src/core/Rsdo.Concordancer.Core/Rsdo.Concordancer.Core.csproj Rsdo.Concordancer.Core/Rsdo.Concordancer.Core.csproj
|
||||
COPY src/core/Rsdo.Concordancer.Data/Rsdo.Concordancer.Data.csproj Rsdo.Concordancer.Data/Rsdo.Concordancer.Data.csproj
|
||||
COPY src/core/Rsdo.Concordancer.Infrastructure/Rsdo.Concordancer.Infrastructure.csproj Rsdo.Concordancer.Infrastructure/Rsdo.Concordancer.Infrastructure.csproj
|
||||
COPY src/core/Rsdo.Concordancer.ServiceModel/Rsdo.Concordancer.ServiceModel.csproj Rsdo.Concordancer.ServiceModel/Rsdo.Concordancer.ServiceModel.csproj
|
||||
COPY src/core/Rsdo.Concordancer.Services/Rsdo.Concordancer.Services.csproj Rsdo.Concordancer.Services/Rsdo.Concordancer.Services.csproj
|
||||
|
||||
WORKDIR /src/apps/Rsdo.Concordancer.Api
|
||||
RUN dotnet restore Rsdo.Concordancer.Api.csproj
|
||||
|
||||
# COPY ALL FILES
|
||||
WORKDIR /src/apps
|
||||
COPY src/apps/Rsdo.Concordancer.Api/. Rsdo.Concordancer.Api/
|
||||
|
||||
WORKDIR /src/core
|
||||
COPY src/core/Rsdo.Concordancer.Core/. Rsdo.Concordancer.Core/
|
||||
COPY src/core/Rsdo.Concordancer.Data/. Rsdo.Concordancer.Data/
|
||||
COPY src/core/Rsdo.Concordancer.Infrastructure/. Rsdo.Concordancer.Infrastructure/
|
||||
COPY src/core/Rsdo.Concordancer.ServiceModel/. Rsdo.Concordancer.ServiceModel/
|
||||
COPY src/core/Rsdo.Concordancer.Services/. Rsdo.Concordancer.Services/
|
||||
|
||||
# BUILD
|
||||
FROM build AS publish
|
||||
WORKDIR /src/apps/Rsdo.Concordancer.Api
|
||||
RUN dotnet publish "Rsdo.Concordancer.Api.csproj" -c Release -o /app/publish
|
||||
|
||||
# COPY TO FINAL
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "Rsdo.Concordancer.Api.dll"]
|
||||
@@ -0,0 +1,16 @@
|
||||
using Hangfire;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Framework;
|
||||
|
||||
public static class HangfireConfigurationExtensions
|
||||
{
|
||||
public static void UseMediator(this IGlobalConfiguration configuration)
|
||||
{
|
||||
var jsonSettings = new JsonSerializerSettings()
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
};
|
||||
configuration.UseSerializerSettings(jsonSettings);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Serilog;
|
||||
using Serilog.Configuration;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.Email;
|
||||
|
||||
namespace Rsdo.Concordancer.Api.Framework;
|
||||
|
||||
public static class SerilogExtensions
|
||||
{
|
||||
public static LoggerConfiguration RsdoEmail(
|
||||
this LoggerSinkConfiguration sinkConfiguration,
|
||||
string fromEmail,
|
||||
string toEmail,
|
||||
string mailServer,
|
||||
int port,
|
||||
bool enableSsl,
|
||||
string userName,
|
||||
string password,
|
||||
string outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}",
|
||||
LogEventLevel restrictedToMinimumLevel = LogEventLevel.Warning,
|
||||
int batchPostingLimit = 100,
|
||||
string mailSubject = "Log Email")
|
||||
{
|
||||
var connectionInfo = new EmailConnectionInfo()
|
||||
{
|
||||
FromEmail = fromEmail,
|
||||
ToEmail = toEmail,
|
||||
EmailSubject = mailSubject,
|
||||
MailServer = mailServer,
|
||||
Port = port,
|
||||
EnableSsl = enableSsl,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
|
||||
{
|
||||
connectionInfo.NetworkCredentials = new NetworkCredential()
|
||||
{
|
||||
UserName = userName,
|
||||
Password = password,
|
||||
};
|
||||
}
|
||||
|
||||
return sinkConfiguration.Email(connectionInfo: connectionInfo, restrictedToMinimumLevel: restrictedToMinimumLevel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Serilog;
|
||||
|
||||
namespace Rsdo.Concordancer.Api;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// Read configuration file
|
||||
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
|
||||
.Build();
|
||||
|
||||
// Create logger
|
||||
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
|
||||
|
||||
// Run application
|
||||
try
|
||||
{
|
||||
Log.Information("Starting web host");
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
return 0;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal(e, "Host terminated unexpectedly");
|
||||
return 1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSerilog()
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureWebHostDefaults(
|
||||
webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
webBuilder.UseWebRoot("./WebApp/build");
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:9184",
|
||||
"sslPort": 44312
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Rsdo.Concordancer.Api": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.4.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Hangfire" Version="1.7.31" />
|
||||
<PackageReference Include="Hangfire.PostgreSql" Version="1.9.9" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.46" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.10" />
|
||||
<PackageReference Include="Rsdo.StyleCop" Version="1.0.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
|
||||
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Email" Version="2.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Rsdo.Concordancer.Data\Rsdo.Concordancer.Data.csproj" />
|
||||
<ProjectReference Include="..\..\core\Rsdo.Concordancer.Infrastructure\Rsdo.Concordancer.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\core\Rsdo.Concordancer.ServiceModel\Rsdo.Concordancer.ServiceModel.csproj" />
|
||||
<ProjectReference Include="..\..\core\Rsdo.Concordancer.Services\Rsdo.Concordancer.Services.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="WebApp" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="WebApp\build\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using Autofac;
|
||||
using Hangfire;
|
||||
using Hangfire.PostgreSql;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Rsdo.Concordancer.Api.Controllers;
|
||||
using Rsdo.Concordancer.Api.Framework;
|
||||
using Rsdo.Concordancer.Core.Constants;
|
||||
using Rsdo.Concordancer.Data.CompositionRoot;
|
||||
using Rsdo.Concordancer.Infrastructure.CompositionRoot;
|
||||
using Rsdo.Concordancer.ServiceModel.Shared;
|
||||
using Rsdo.Concordancer.Services.CompositionRoot;
|
||||
using Rsdo.Concordancer.Services.Framework.Cache;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Rsdo.Concordancer.Api;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddCors(
|
||||
opt =>
|
||||
{
|
||||
opt.AddPolicy(
|
||||
"CorsPolicy",
|
||||
policy =>
|
||||
{
|
||||
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
|
||||
});
|
||||
});
|
||||
services.AddControllers()
|
||||
.AddJsonOptions(
|
||||
opts =>
|
||||
{
|
||||
// Bind strings to enums
|
||||
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
});
|
||||
services.AddSwaggerGen(
|
||||
c =>
|
||||
{
|
||||
c.SwaggerDoc(
|
||||
ServiceApiInfo.ApiGroupConcordancer,
|
||||
info: new OpenApiInfo()
|
||||
{
|
||||
Title = $"{ServiceApiInfo.ServiceName} Concordancer API",
|
||||
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
|
||||
});
|
||||
c.SwaggerDoc(
|
||||
ServiceApiInfo.ApiGroupDashboard,
|
||||
info: new OpenApiInfo()
|
||||
{
|
||||
Title = $"{ServiceApiInfo.ServiceName} Dashboard API",
|
||||
Version = $"v{ServiceApiInfo.ServiceVersion.ToString(3)}",
|
||||
});
|
||||
|
||||
// enable attribute annotations
|
||||
c.EnableAnnotations();
|
||||
|
||||
// include code documentation to the swagger doc
|
||||
ConfigureSwaggerApiDoc(c, Assembly.GetExecutingAssembly(), typeof(ExecutionResult).Assembly);
|
||||
});
|
||||
services.AddHangfire(
|
||||
x =>
|
||||
{
|
||||
// It would be better to use ConnectionStringProvider, but in this case
|
||||
// we would have to build the container which would (at this point) double singletons.
|
||||
// So we are duplicated code from ConnectionStringProvider
|
||||
var connectionString = Configuration[ConfigurationKey.Database.MasterConnectionString];
|
||||
x.UsePostgreSqlStorage(connectionString);
|
||||
x.UseMediator();
|
||||
});
|
||||
services.AddHangfireServer();
|
||||
services.AddHttpClient();
|
||||
}
|
||||
|
||||
public void ConfigureSwaggerApiDoc(SwaggerGenOptions options, params Assembly[] assemblies)
|
||||
{
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
var xmlFile = $"{assembly.GetName().Name}.xml";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
options.IncludeXmlComments(xmlPath);
|
||||
}
|
||||
}
|
||||
|
||||
public void ConfigureContainer(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterModule(new ServicesModule());
|
||||
builder.RegisterModule(new InfrastructureModule());
|
||||
builder.RegisterModule(new DataModule());
|
||||
builder.RegisterBuildCallback(
|
||||
(c) =>
|
||||
{
|
||||
var warmUps = c.Resolve<IEnumerable<ICacheWarmUp>>();
|
||||
foreach (var warmUp in warmUps)
|
||||
{
|
||||
warmUp.WarmUp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(
|
||||
c =>
|
||||
{
|
||||
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupConcordancer}/swagger.json", $"{ServiceApiInfo.ServiceName} Concordancer API");
|
||||
c.SwaggerEndpoint($"{ServiceApiInfo.ApiGroupDashboard}/swagger.json", $"{ServiceApiInfo.ServiceName} Dashboard API");
|
||||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.UseCors("CorsPolicy");
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(
|
||||
endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapHangfireDashboard("/hangfire");
|
||||
endpoints.MapFallbackToController("Index", "WebApp");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -0,0 +1,70 @@
|
||||
# Getting Started with Create React App
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "concordancer-web",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"bootstrap": "^5.2.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-i18next": "^12.0.0",
|
||||
"react-query": "^3.39.2",
|
||||
"react-router-dom": "^6.4.3",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"sass": "^1.56.1"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>TP | Konkordančnik</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,900;1,100;1,400&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import {
|
||||
QueryClient,
|
||||
QueryClientProvider
|
||||
} from 'react-query'
|
||||
import ConcordanceIndex from './pages/concordance/ConcordanceIndex';
|
||||
import ConcordanceResults from './pages/concordance/ConcordanceResults';
|
||||
import ListIndex from './pages/list/ListIndex';
|
||||
import ListResults from './pages/list/ListResults';
|
||||
import NoCorpus from './pages/NoCorpus';
|
||||
|
||||
function App() {
|
||||
const queryClient = new QueryClient();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Routes>
|
||||
<Route path='/:corpusId/concordance' element={<ConcordanceIndex />} />
|
||||
<Route path='/:corpusId/concordance/search' element={<ConcordanceResults />} />
|
||||
<Route path='/:corpusId/list' element={<ListIndex />} />
|
||||
<Route path='/:corpusId/list/search' element={<ListResults />} />
|
||||
<Route path='/:corpusId/*' element={<ConcordanceIndex />} />
|
||||
<Route path='*' element={<NoCorpus />} />
|
||||
</Routes>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.292893 0.292893C0.683417 -0.0976311 1.31658 -0.0976311 1.70711 0.292893L7 5.58579L12.2929 0.292893C12.6834 -0.0976311 13.3166 -0.0976311 13.7071 0.292893C14.0976 0.683417 14.0976 1.31658 13.7071 1.70711L7.70711 7.70711C7.31658 8.09763 6.68342 8.09763 6.29289 7.70711L0.292893 1.70711C-0.0976311 1.31658 -0.0976311 0.683417 0.292893 0.292893Z" fill="#006cb7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 513 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.29289 0.292893C6.68342 -0.0976311 7.31658 -0.0976311 7.70711 0.292893L13.7071 6.29289C14.0976 6.68342 14.0976 7.31658 13.7071 7.70711C13.3166 8.09763 12.6834 8.09763 12.2929 7.70711L7 2.41421L1.70711 7.70711C1.31658 8.09763 0.683417 8.09763 0.292893 7.70711C-0.0976311 7.31658 -0.0976311 6.68342 0.292893 6.29289L6.29289 0.292893Z" fill="#006cb7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 502 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.7071 5.29289C19.0976 5.68342 19.0976 6.31658 18.7071 6.70711L6.70711 18.7071C6.31658 19.0976 5.68342 19.0976 5.29289 18.7071C4.90237 18.3166 4.90237 17.6834 5.29289 17.2929L17.2929 5.29289C17.6834 4.90237 18.3166 4.90237 18.7071 5.29289Z" fill="#848C90"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 5.29289C5.68342 4.90237 6.31658 4.90237 6.70711 5.29289L18.7071 17.2929C19.0976 17.6834 19.0976 18.3166 18.7071 18.7071C18.3166 19.0976 17.6834 19.0976 17.2929 18.7071L5.29289 6.70711C4.90237 6.31658 4.90237 5.68342 5.29289 5.29289Z" fill="#848C90"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 721 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#006CB7"/>
|
||||
<path d="M12.5781 6.625V18H11.0703V6.625H12.5781Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 217 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#B6BEC4"/>
|
||||
<path d="M12.5781 6.625V18H11.0703V6.625H12.5781Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 217 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 10C10.4477 10 10 10.4477 10 11V20C10 20.5523 10.4477 21 11 21H20C20.5523 21 21 20.5523 21 20V11C21 10.4477 20.5523 10 20 10H11ZM8 11C8 9.34315 9.34315 8 11 8H20C21.6569 8 23 9.34315 23 11V20C23 21.6569 21.6569 23 20 23H11C9.34315 23 8 21.6569 8 20V11Z" fill="#006CB7"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C3.73478 3 3.48043 3.10536 3.29289 3.29289C3.10536 3.48043 3 3.73478 3 4V13C3 13.2652 3.10536 13.5196 3.29289 13.7071C3.48043 13.8946 3.73478 14 4 14H5C5.55228 14 6 14.4477 6 15C6 15.5523 5.55228 16 5 16H4C3.20435 16 2.44129 15.6839 1.87868 15.1213C1.31607 14.5587 1 13.7956 1 13V4C1 3.20435 1.31607 2.44129 1.87868 1.87868C2.44129 1.31607 3.20435 1 4 1H13C13.7956 1 14.5587 1.31607 15.1213 1.87868C15.6839 2.44129 16 3.20435 16 4V5C16 5.55228 15.5523 6 15 6C14.4477 6 14 5.55228 14 5V4C14 3.73478 13.8946 3.48043 13.7071 3.29289C13.5196 3.10536 13.2652 3 13 3H4Z" fill="#006CB7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 2C6.02944 2 2 6.02944 2 11C2 15.9706 6.02944 20 11 20C15.9706 20 20 15.9706 20 11C20 6.02944 15.9706 2 11 2ZM0 11C0 4.92487 4.92487 0 11 0C17.0751 0 22 4.92487 22 11C22 17.0751 17.0751 22 11 22C4.92487 22 0 17.0751 0 11Z" fill="#848C91"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.2581 7.02432C10.7926 6.94447 10.3138 7.03195 9.90664 7.27127C9.49944 7.51058 9.19007 7.88629 9.03333 8.33184C8.85006 8.85283 8.27915 9.12661 7.75816 8.94333C7.23717 8.76006 6.96339 8.18915 7.14667 7.66816C7.46014 6.77705 8.07887 6.02563 8.89327 5.547C9.70767 5.06837 10.6652 4.89341 11.5962 5.05311C12.5273 5.2128 13.3718 5.69686 13.9801 6.41953C14.5883 7.14205 14.9213 8.05648 14.92 9.00091C14.9197 10.0711 14.3569 10.889 13.7751 11.4464C13.1931 12.004 12.5031 12.3909 12.0159 12.6243C11.977 12.6429 11.9487 12.6696 11.933 12.6926C11.9257 12.7033 11.9225 12.7113 11.9211 12.7154C11.92 12.719 11.92 12.7205 11.92 12.7207V13C11.92 13.5523 11.4723 14 10.92 14C10.3677 14 9.92 13.5523 9.92 13V12.7208C9.92 11.8509 10.4686 11.1479 11.1518 10.8206C11.5483 10.6307 12.0263 10.3522 12.3915 10.0023C12.7567 9.65234 12.92 9.32103 12.92 9L12.92 8.99851C12.9207 8.52619 12.7542 8.06886 12.4501 7.70753C12.1459 7.34619 11.7236 7.10417 11.2581 7.02432Z" fill="#848C91"/>
|
||||
<path d="M12 16C12 16.5523 11.5523 17 11 17C10.4477 17 10 16.5523 10 16C10 15.4477 10.4477 15 11 15C11.5523 15 12 15.4477 12 16Z" fill="#848C91"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="25" height="22" viewBox="0 0 25 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.1667 0.5C8.36834 0.5 3.66667 5.20167 3.66667 11H0.166672L4.70501 15.5383L4.78667 15.7017L9.50001 11H6.00001C6.00001 6.485 9.65167 2.83333 14.1667 2.83333C18.6817 2.83333 22.3333 6.485 22.3333 11C22.3333 15.515 18.6817 19.1667 14.1667 19.1667C11.915 19.1667 9.87334 18.245 8.40334 16.7633L6.74667 18.42C8.64834 20.3217 11.2617 21.5 14.1667 21.5C19.965 21.5 24.6667 16.7983 24.6667 11C24.6667 5.20167 19.965 0.5 14.1667 0.5ZM13 6.33333V12.1667L17.9583 15.1067L18.8567 13.6133L14.75 11.175V6.33333H13Z" fill="#848C91"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 633 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 2C6.02944 2 2 6.02944 2 11C2 15.9706 6.02944 20 11 20C15.9706 20 20 15.9706 20 11C20 6.02944 15.9706 2 11 2ZM0 11C0 4.92487 4.92487 0 11 0C17.0751 0 22 4.92487 22 11C22 17.0751 17.0751 22 11 22C4.92487 22 0 17.0751 0 11Z" fill="#F5F5F5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 11C0 10.4477 0.447715 10 1 10H21C21.5523 10 22 10.4477 22 11C22 11.5523 21.5523 12 21 12H1C0.447715 12 0 11.5523 0 11Z" fill="#F5F5F5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.00023 11C8.06877 14.0748 9.12625 17.0352 11 19.4492C12.8737 17.0352 13.9312 14.0748 13.9998 11C13.9312 7.92516 12.8737 4.96485 11 2.5508C9.12626 4.96485 8.06877 7.92516 8.00023 11ZM11 1L10.2617 0.325577C7.59689 3.24291 6.08251 7.02885 6.00022 10.9792C5.99993 10.9931 5.99993 11.0069 6.00022 11.0208C6.08251 14.9711 7.59689 18.7571 10.2617 21.6744C10.4511 21.8818 10.7191 22 11 22C11.2809 22 11.5489 21.8818 11.7383 21.6744C14.4031 18.7571 15.9175 14.9711 15.9998 11.0208C16.0001 11.0069 16.0001 10.9931 15.9998 10.9792C15.9175 7.02885 14.4031 3.24291 11.7383 0.325577L11 1Z" fill="#F5F5F5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#006CB7"/>
|
||||
<path d="M14.8828 15.125C14.8828 14.8594 14.8411 14.625 14.7578 14.4219C14.6797 14.2135 14.5391 14.026 14.3359 13.8594C14.138 13.6927 13.862 13.5339 13.5078 13.3828C13.1589 13.2318 12.7161 13.0781 12.1797 12.9219C11.6172 12.7552 11.1094 12.5703 10.6562 12.3672C10.2031 12.1589 9.8151 11.9219 9.49219 11.6562C9.16927 11.3906 8.92188 11.0859 8.75 10.7422C8.57812 10.3984 8.49219 10.0052 8.49219 9.5625C8.49219 9.11979 8.58333 8.71094 8.76562 8.33594C8.94792 7.96094 9.20833 7.63542 9.54688 7.35938C9.89062 7.07812 10.2995 6.85938 10.7734 6.70312C11.2474 6.54688 11.776 6.46875 12.3594 6.46875C13.2135 6.46875 13.9375 6.63281 14.5312 6.96094C15.1302 7.28385 15.5859 7.70833 15.8984 8.23438C16.2109 8.75521 16.3672 9.3125 16.3672 9.90625H14.8672C14.8672 9.47917 14.776 9.10156 14.5938 8.77344C14.4115 8.4401 14.1354 8.17969 13.7656 7.99219C13.3958 7.79948 12.9271 7.70312 12.3594 7.70312C11.8229 7.70312 11.3802 7.78385 11.0312 7.94531C10.6823 8.10677 10.4219 8.32552 10.25 8.60156C10.0833 8.8776 10 9.19271 10 9.54688C10 9.78646 10.0495 10.0052 10.1484 10.2031C10.2526 10.3958 10.4115 10.5755 10.625 10.7422C10.8438 10.9089 11.1198 11.0625 11.4531 11.2031C11.7917 11.3438 12.1953 11.4792 12.6641 11.6094C13.3099 11.7917 13.8672 11.9948 14.3359 12.2188C14.8047 12.4427 15.1901 12.6953 15.4922 12.9766C15.7995 13.2526 16.026 13.5677 16.1719 13.9219C16.3229 14.2708 16.3984 14.6667 16.3984 15.1094C16.3984 15.5729 16.3047 15.9922 16.1172 16.3672C15.9297 16.7422 15.6615 17.0625 15.3125 17.3281C14.9635 17.5938 14.5443 17.7995 14.0547 17.9453C13.5703 18.0859 13.0286 18.1562 12.4297 18.1562C11.9036 18.1562 11.3854 18.0833 10.875 17.9375C10.3698 17.7917 9.90885 17.5729 9.49219 17.2812C9.08073 16.9896 8.75 16.6302 8.5 16.2031C8.25521 15.7708 8.13281 15.2708 8.13281 14.7031H9.63281C9.63281 15.0938 9.70833 15.4297 9.85938 15.7109C10.0104 15.987 10.2161 16.2161 10.4766 16.3984C10.7422 16.5807 11.0417 16.7161 11.375 16.8047C11.7135 16.888 12.0651 16.9297 12.4297 16.9297C12.9557 16.9297 13.401 16.8568 13.7656 16.7109C14.1302 16.5651 14.4062 16.3568 14.5938 16.0859C14.7865 15.8151 14.8828 15.4948 14.8828 15.125Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="12" cy="12" r="12" fill="#B6BEC4"/>
|
||||
<path d="M14.8828 15.125C14.8828 14.8594 14.8411 14.625 14.7578 14.4219C14.6797 14.2135 14.5391 14.026 14.3359 13.8594C14.138 13.6927 13.862 13.5339 13.5078 13.3828C13.1589 13.2318 12.7161 13.0781 12.1797 12.9219C11.6172 12.7552 11.1094 12.5703 10.6562 12.3672C10.2031 12.1589 9.8151 11.9219 9.49219 11.6562C9.16927 11.3906 8.92188 11.0859 8.75 10.7422C8.57812 10.3984 8.49219 10.0052 8.49219 9.5625C8.49219 9.11979 8.58333 8.71094 8.76562 8.33594C8.94792 7.96094 9.20833 7.63542 9.54688 7.35938C9.89062 7.07812 10.2995 6.85938 10.7734 6.70312C11.2474 6.54688 11.776 6.46875 12.3594 6.46875C13.2135 6.46875 13.9375 6.63281 14.5312 6.96094C15.1302 7.28385 15.5859 7.70833 15.8984 8.23438C16.2109 8.75521 16.3672 9.3125 16.3672 9.90625H14.8672C14.8672 9.47917 14.776 9.10156 14.5938 8.77344C14.4115 8.4401 14.1354 8.17969 13.7656 7.99219C13.3958 7.79948 12.9271 7.70312 12.3594 7.70312C11.8229 7.70312 11.3802 7.78385 11.0312 7.94531C10.6823 8.10677 10.4219 8.32552 10.25 8.60156C10.0833 8.8776 10 9.19271 10 9.54688C10 9.78646 10.0495 10.0052 10.1484 10.2031C10.2526 10.3958 10.4115 10.5755 10.625 10.7422C10.8438 10.9089 11.1198 11.0625 11.4531 11.2031C11.7917 11.3438 12.1953 11.4792 12.6641 11.6094C13.3099 11.7917 13.8672 11.9948 14.3359 12.2188C14.8047 12.4427 15.1901 12.6953 15.4922 12.9766C15.7995 13.2526 16.026 13.5677 16.1719 13.9219C16.3229 14.2708 16.3984 14.6667 16.3984 15.1094C16.3984 15.5729 16.3047 15.9922 16.1172 16.3672C15.9297 16.7422 15.6615 17.0625 15.3125 17.3281C14.9635 17.5938 14.5443 17.7995 14.0547 17.9453C13.5703 18.0859 13.0286 18.1562 12.4297 18.1562C11.9036 18.1562 11.3854 18.0833 10.875 17.9375C10.3698 17.7917 9.90885 17.5729 9.49219 17.2812C9.08073 16.9896 8.75 16.6302 8.5 16.2031C8.25521 15.7708 8.13281 15.2708 8.13281 14.7031H9.63281C9.63281 15.0938 9.70833 15.4297 9.85938 15.7109C10.0104 15.987 10.2161 16.2161 10.4766 16.3984C10.7422 16.5807 11.0417 16.7161 11.375 16.8047C11.7135 16.888 12.0651 16.9297 12.4297 16.9297C12.9557 16.9297 13.401 16.8568 13.7656 16.7109C14.1302 16.5651 14.4062 16.3568 14.5938 16.0859C14.7865 15.8151 14.8828 15.4948 14.8828 15.125Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 2C5.13401 2 2 5.13401 2 9C2 12.866 5.13401 16 9 16C12.866 16 16 12.866 16 9C16 5.13401 12.866 2 9 2ZM0 9C0 4.02944 4.02944 0 9 0C13.9706 0 18 4.02944 18 9C18 13.9706 13.9706 18 9 18C4.02944 18 0 13.9706 0 9Z" fill="#848C91"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.9429 13.9429C14.3334 13.5524 14.9666 13.5524 15.3571 13.9429L19.7071 18.2929C20.0976 18.6834 20.0976 19.3166 19.7071 19.7071C19.3166 20.0976 18.6834 20.0976 18.2929 19.7071L13.9429 15.3571C13.5524 14.9666 13.5524 14.3334 13.9429 13.9429Z" fill="#848C91"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 690 B |
@@ -0,0 +1,30 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import ConcordanceAggregationItem from './ConcordanceAggregationItem';
|
||||
|
||||
import styles from './ConcordanceAggregation.module.scss';
|
||||
import chevronDown from '../../assets/chevron-down.svg';
|
||||
import chevronUp from '../../assets/chevron-up.svg'
|
||||
|
||||
const ConcordanceAggregation = (props) => {
|
||||
const expandable = props.items.length > 5;
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const items = expandable && !isExpanded ? props.items.slice(0, 5) : props.items;
|
||||
|
||||
const expandHandler = () => {
|
||||
setIsExpanded((prevState) => !prevState);
|
||||
};
|
||||
|
||||
const headerEl = expandable ? <h2 onClick={expandHandler}>{props.title} <img className='float-end' src={isExpanded ? chevronUp : chevronDown} alt={isExpanded ? 'Collapse' : 'Expand'} /></h2> : <h2>{props.title}</h2>
|
||||
|
||||
return (
|
||||
<div className={styles.aggregation}>
|
||||
{headerEl}
|
||||
<ul>
|
||||
{items.map(x => <ConcordanceAggregationItem key={x.key} filterKey={x.key} title={x.title} count={x.count} />)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceAggregation;
|
||||
@@ -0,0 +1,21 @@
|
||||
@import '../../variables';
|
||||
|
||||
.aggregation {
|
||||
h2 {
|
||||
border-bottom: 1px solid $border-color;
|
||||
color: $primary-color;
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.9rem;
|
||||
padding-bottom: 0.7rem;
|
||||
|
||||
img {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0 0 2.7rem 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import useSearch from '../../hooks/use-search';
|
||||
import styles from './ConcordanceAggregationItem.module.scss';
|
||||
|
||||
const ConcordanceAggregationItem = (props) => {
|
||||
const search = useSearch();
|
||||
const isSelected = search.isFiltered('TextIds', props.filterKey) === true;
|
||||
const link = isSelected ? search.getClearFilterLink('TextIds', props.filterKey) : search.getFilterLink('TextIds', props.filterKey);
|
||||
|
||||
return (
|
||||
<li className={styles.aggregationItem}><Link to={link}>{isSelected && <span>X - </span>}{props.title}<span className='float-end'>{props.count}</span></Link></li>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceAggregationItem;
|
||||
@@ -0,0 +1,12 @@
|
||||
@import '../../variables';
|
||||
|
||||
.aggregationItem {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.8rem;
|
||||
padding-bottom: 0.8rem;
|
||||
|
||||
a {
|
||||
color: $text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import ConcordanceAlternateSearch from './ConcordanceAlternateSearch';
|
||||
import ConcordanceAggregation from './ConcordanceAggregation';
|
||||
import styles from './ConcordanceAggregations.module.scss';
|
||||
|
||||
const ConcordanceAggregations = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className={styles.aggregations}>
|
||||
<ConcordanceAlternateSearch title={t(`concordance.aggregation${props.lemmasAlternateSearch.type}`)} items={props.lemmasAlternateSearch.items} />
|
||||
{props.aggregations.map(x => <ConcordanceAggregation key={x.type} title={t(`concordance.aggregation${x.type}`)} items={x.items} />)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceAggregations;
|
||||
@@ -0,0 +1,8 @@
|
||||
.aggregations {
|
||||
padding-top: 1.8rem;
|
||||
padding-right: 6.4rem;
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import ConcordanceAlternateSearchItem from './ConcordanceAlternateSearchItem';
|
||||
import styles from './ConcordanceAlternateSearch.module.scss';
|
||||
|
||||
const ConcordanceAlternateSearch = (props) => {
|
||||
return (
|
||||
<div className={styles.alternateSearch}>
|
||||
<h2>{props.title}</h2>
|
||||
<ul>
|
||||
{props.items.map((x,i) => <ConcordanceAlternateSearchItem key={i} filterKey={x.key} title={x.title} count={x.count} search={x.search} />)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceAlternateSearch;
|
||||
@@ -0,0 +1,21 @@
|
||||
@import '../../variables';
|
||||
|
||||
.alternateSearch {
|
||||
h2 {
|
||||
border-bottom: 1px solid $border-color;
|
||||
color: $primary-color;
|
||||
font-size: 1.6rem;
|
||||
line-height: 1.9rem;
|
||||
padding-bottom: 0.7rem;
|
||||
|
||||
img {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0 0 2.7rem 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import useSearch from '../../hooks/use-search';
|
||||
import styles from './ConcordanceAlternateSearchItem.module.scss';
|
||||
|
||||
const ConcordanceAlternateSearchItem = (props) => {
|
||||
const search = useSearch();
|
||||
const link = search.getAlternateSearchLink(props.search);
|
||||
return (
|
||||
<li className={styles.alternateSearchItem}><Link to={link}>{props.title}<span className='float-end'>{props.count}</span></Link></li>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceAlternateSearchItem;
|
||||
@@ -0,0 +1,12 @@
|
||||
@import '../../variables';
|
||||
|
||||
.alternateSearchItem {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.8rem;
|
||||
padding-bottom: 0.8rem;
|
||||
|
||||
a {
|
||||
color: $text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import { useState } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useSearch from '../../hooks/use-search';
|
||||
|
||||
import Spinner from '../shared/Spinner';
|
||||
import ConcordanceDetailsParagraph from './ConcordanceDetailsParagraph';
|
||||
import ConcordanceDetailsText from './ConcordanceDetailsText';
|
||||
import ConcordanceDetailsTokens from './ConcordanceDetailsTokens';
|
||||
|
||||
import closeIcon from '../../assets/close.svg';
|
||||
import styles from './ConcordanceDetails.module.scss';
|
||||
|
||||
|
||||
const ConcordanceDetails = (props) => {
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
const search = useSearch();
|
||||
const body = search.getDetailsRequest(props.paragraphId, props.tokenOrder);
|
||||
|
||||
const fetchDetails = () => fetch(`${window.baseAppPath}/concordancer/corpus/${search.corpusId}/concordances/details`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((res) => res.json());
|
||||
|
||||
const { isLoading, isError, data, error } = useQuery(['details', body], fetchDetails, { refetchOnWindowFocus: false });
|
||||
|
||||
const selectParagraphTab = (e) => {
|
||||
e.preventDefault();
|
||||
setActiveTab(0);
|
||||
};
|
||||
|
||||
const selectTokensTab = (e) => {
|
||||
e.preventDefault();
|
||||
setActiveTab(1);
|
||||
}
|
||||
|
||||
if (!isLoading && data) {
|
||||
return (
|
||||
<div className={styles.details}>
|
||||
<div className={styles.tabs}>
|
||||
<ul>
|
||||
<li className={activeTab === 0 ? styles.active : null}><button type='button' className='btn btn-link' onClick={selectParagraphTab}>{t('concordance.detailsParagraph')}</button></li>
|
||||
<li className={activeTab === 1 ? styles.active : null}><button type='button' className='btn btn-link' onClick={selectTokensTab} >{t('concordance.detailsAnnotation')}</button></li>
|
||||
</ul>
|
||||
<button type='button' className={`btn btn-link ${styles.close}`} onClick={props.onClose}><img src={closeIcon} alt='Close' /></button>
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className={`col-lg-9 ${styles.mainContent}`}>
|
||||
{activeTab === 0 && <ConcordanceDetailsParagraph tokens={data.tokens} />}
|
||||
{activeTab === 1 && <ConcordanceDetailsTokens tokens={data.tokens} />}
|
||||
</div>
|
||||
<div className={`col-lg-3 ${styles.textInfo}`}>
|
||||
<ConcordanceDetailsText source={data.sourceFile} year={data.year} title={data.title} author={data.author} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
let content = <></>;
|
||||
if (isLoading) {
|
||||
content = <Spinner></Spinner>
|
||||
} else if (isError) {
|
||||
content = <p>{t('shared.searchError')}</p>
|
||||
} else if (!isLoading && data && data.items.length === 0) {
|
||||
content = <p>{t('shared.noResults')}</p>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.details}>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ConcordanceDetails;
|
||||
@@ -0,0 +1,72 @@
|
||||
@import '../../variables';
|
||||
|
||||
.details {
|
||||
background-color: #ffffff;
|
||||
border-radius: 0.8rem;
|
||||
box-shadow: 0 0.4rem 1.6rem rgba(0, 0, 0, 0.08);
|
||||
margin: 1.6rem 0;
|
||||
padding: 2.4rem 2.8rem;
|
||||
position: relative;
|
||||
|
||||
.tabs {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 2.2rem;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
padding: 0 2rem;
|
||||
|
||||
button {
|
||||
color: $text-color-secondary;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-bottom: 3px solid $primary-color;
|
||||
|
||||
button {
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 2.8rem;
|
||||
top: 2.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mainContent {
|
||||
border-right: 2px solid $border-color;
|
||||
padding-right: 3rem;
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
border-right: none;
|
||||
margin-bottom: 3rem;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.textInfo {
|
||||
padding-left: 3rem;
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import ConcordanceTokens from './ConcordanceTokens';
|
||||
|
||||
const ConcordanceDetailsParagraph = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<ConcordanceTokens tokens={props.tokens} />
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
export default ConcordanceDetailsParagraph;
|
||||
@@ -0,0 +1,31 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import sytles from './ConcordanceDetailsText.module.scss';
|
||||
|
||||
const ConcordanceDetailsText = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={sytles.textInfo}>
|
||||
<h5>{t('concordance.detailsTextSource')}</h5>
|
||||
<p>{props.source}</p>
|
||||
</div>
|
||||
<div className={sytles.textInfo}>
|
||||
<h5>{t('concordance.detailsTextYear')}</h5>
|
||||
<p>{props.year}</p>
|
||||
</div>
|
||||
<div className={sytles.textInfo}>
|
||||
<h5>{t('concordance.detailsTextTitle')}</h5>
|
||||
<p>{props.title}</p>
|
||||
</div>
|
||||
<div className={sytles.textInfo}>
|
||||
<h5>{t('concordance.detailsTextAuthor')}</h5>
|
||||
<p>{props.author}</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceDetailsText;
|
||||
@@ -0,0 +1,22 @@
|
||||
@import '../../variables';
|
||||
|
||||
.textInfo {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: $primary-color;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 1.6rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import ConcordanceDetailsTokensItem from "./ConcordanceDetailsTokensItem";
|
||||
import styles from './ConcordanceDetailsTokens.module.scss';
|
||||
|
||||
const ConcordanceDetailsTokens = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`row ${styles.header}`}>
|
||||
<div className='col-lg-4'>{t('concordance.detailsAnnotationWord')}</div>
|
||||
<div className='col-lg-4'>{t('concordance.detailsAnnotationBasicForm')}</div>
|
||||
<div className='col-lg-4'>{t('concordance.detailsAnnotationPos')}</div>
|
||||
</div>
|
||||
{props.tokens.filter(x => x.type === 'Word').map((x, i) => <ConcordanceDetailsTokensItem key={i} token={x} />)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceDetailsTokens;
|
||||
@@ -0,0 +1,7 @@
|
||||
@import '../../variables';
|
||||
|
||||
.header {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import ConcordanceToken from './ConcordanceToken';
|
||||
|
||||
import styles from './ConcordanceDetailsTokensItem.module.scss';
|
||||
|
||||
const ConcordanceDetailsTokensItem = (props) => {
|
||||
const token = props.token;
|
||||
return (
|
||||
<div className={`row ${styles.item}`}>
|
||||
<div className='col-lg-4'><ConcordanceToken content={token.form} isCenterMatch={token.isCenterMatch} isWordInContextMatch={token.isWordInContextMatch} /></div>
|
||||
<div className='col-lg-4 text-secondary'><ConcordanceToken content={token.lemma} isCenterMatch={token.isCenterMatch} isWordInContextMatch={token.isWordInContextMatch} /></div>
|
||||
<div className='col-lg-4 text-secondary'><ConcordanceToken content={token.msdDescription} isCenterMatch={token.isCenterMatch} isWordInContextMatch={token.isWordInContextMatch} /></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceDetailsTokensItem;
|
||||
@@ -0,0 +1,7 @@
|
||||
@import '../../variables';
|
||||
|
||||
.item {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import SearchHelp from '../shared/SearchHelp.js';
|
||||
|
||||
const ConcordanceHelp = () => {
|
||||
return (
|
||||
<SearchHelp>
|
||||
<ul>
|
||||
<li>
|
||||
<h4>rdeča jagoda</h4>
|
||||
<p><em>rdeča jagoda, rdeče jagode, rdeči jagodi</em></p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>"rdečimi jagodami"</h4>
|
||||
<p><em>rdečimi jagodami</em></p>
|
||||
</li>
|
||||
</ul>
|
||||
</SearchHelp>
|
||||
)
|
||||
};
|
||||
|
||||
export default ConcordanceHelp;
|
||||
@@ -0,0 +1,14 @@
|
||||
import { useState } from 'react';
|
||||
import ConcordanceListItem from './ConcordanceListItem';
|
||||
|
||||
const ConcordanceList = (props) => {
|
||||
const [expandedIndex, setExpandedIndex] = useState(null);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{props.items.map((x, i) => <ConcordanceListItem key={i} index={i} expanded={i === expandedIndex} item={x} toggleDetails={(index) => setExpandedIndex(index)} />)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceList;
|
||||
@@ -0,0 +1,17 @@
|
||||
import ConcordanceDetails from './ConcordanceDetails';
|
||||
import ConcordanceTokens from './ConcordanceTokens';
|
||||
import styles from './ConcordanceListItem.module.scss';
|
||||
|
||||
const ConcordanceListItem = (props) => {
|
||||
return (
|
||||
<>
|
||||
<div className={`row ${styles.item}`} onClick={() => { props.toggleDetails(props.index) }}>
|
||||
<div className='col text-end'><ConcordanceTokens tokens={props.item.leftContext} /> </div>
|
||||
<div className='col'><ConcordanceTokens tokens={[props.item.centerContext]} /> <ConcordanceTokens tokens={props.item.rightContext} /></div>
|
||||
</div>
|
||||
{props.expanded && <ConcordanceDetails paragraphId={props.item.paragraphId} tokenOrder={props.item.centerContext.tokenOrder} onClose={() => { props.toggleDetails(null) }} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceListItem;
|
||||
@@ -0,0 +1,8 @@
|
||||
@import '../../variables';
|
||||
|
||||
.item {
|
||||
border-bottom: 1px solid $border-color;
|
||||
cursor: pointer;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const ConcordanceTitle = () => {
|
||||
return (
|
||||
<h1>Iskanje po konkordancah</h1>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceTitle;
|
||||
@@ -0,0 +1,14 @@
|
||||
import styles from './ConcordanceToken.module.scss';
|
||||
|
||||
const ConcordanceToken = (props) => {
|
||||
if (props.isCenterMatch === true) {
|
||||
return <span className={styles.center}>{props.content}</span>
|
||||
} else if (props.isWordInContextMatch === true) {
|
||||
return <em className={styles.wordInContext}>{props.content}</em>
|
||||
} else {
|
||||
return <>{props.content}</>
|
||||
}
|
||||
};
|
||||
|
||||
export default ConcordanceToken;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@import '../../variables';
|
||||
|
||||
.center,
|
||||
.wordInContext {
|
||||
color: $primary-color;
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import ConcordanceToken from "./ConcordanceToken";
|
||||
|
||||
const ConcordanceTokens = (props) => {
|
||||
return (
|
||||
<>
|
||||
{props.tokens.map((x,i) => <ConcordanceToken content={x.form} isCenterMatch={x.isCenterMatch} isWordInContextMatch={x.isWordInContextMatch} key={i} />)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConcordanceTokens;
|
||||
@@ -0,0 +1,29 @@
|
||||
import styles from './IndexMenu.module.scss';
|
||||
import logo from '../../assets/logo.png';
|
||||
import langIcon from '../../assets/language.svg';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const IndexTopBar = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const changeLanguageTitle = i18n.language === 'sl' ? 'English' : 'Slovensko';
|
||||
const changeLanguageCode = i18n.language === 'sl' ? 'EN' : 'SL';
|
||||
|
||||
const languageClickHandler = () => {
|
||||
const newLanguage = i18n.language === 'sl' ? 'en' : 'sl';
|
||||
i18n.changeLanguage(newLanguage);
|
||||
localStorage.setItem('language', newLanguage);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.menu}>
|
||||
<div className='container-fluid'>
|
||||
<div className='row align-items-center'>
|
||||
<div className='col'><img src={logo} alt='Logo' /></div>
|
||||
<div className={`col ${styles.links}`}><button type='button' onClick={languageClickHandler}><img src={langIcon} alt={changeLanguageTitle} />{changeLanguageCode}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexTopBar;
|
||||
@@ -0,0 +1,25 @@
|
||||
@import '../../variables';
|
||||
|
||||
.menu {
|
||||
background-color: $primary-color;
|
||||
height: 15.4rem;
|
||||
|
||||
:global(.container-fluid),
|
||||
:global(.row) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.links {
|
||||
text-align: right;
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: #f5f5f5;
|
||||
|
||||
img {
|
||||
margin-right: 0.625rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from 'react-query';
|
||||
import useSearch from '../../hooks/use-search';
|
||||
import styles from './IndexStatistics.module.scss';
|
||||
|
||||
const IndexStatistics = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const search = useSearch();
|
||||
const corpusId = search.corpusId;
|
||||
|
||||
const fetchStatistics = () => fetch(`${window.baseAppPath}/concordancer/corpus/${corpusId}/stats`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((res) => {
|
||||
return res.json();
|
||||
});
|
||||
|
||||
const { isLoading, isSuccess, isError, data, error } = useQuery(['statistics', corpusId], fetchStatistics, { keepPreviousData: true, refetchOnWindowFocus: false });
|
||||
|
||||
return (
|
||||
<div className={styles.stats}>
|
||||
<div className='row'>
|
||||
<div className={`col-md-4 ${styles.counter}`}><h2>{(!isLoading && isSuccess) ? data.texts : "..."}</h2><p>{t('shared.countTexts')}</p></div>
|
||||
<div className={`col-md-4 ${styles.counter}`}><h2>{(!isLoading && isSuccess) ? data.sentences : "..."}</h2><p>{t('shared.countSentences')}</p></div>
|
||||
<div className={`col-md-4 ${styles.counter}`}><h2>{(!isLoading && isSuccess) ? data.words : "..."}</h2><p>{t('shared.countWords')}</p></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexStatistics;
|
||||
@@ -0,0 +1,35 @@
|
||||
@import '../../variables';
|
||||
|
||||
.stats {
|
||||
background: #ffffff;
|
||||
border-radius: 1.2rem;
|
||||
box-shadow: 0 0.4rem 2rem rgba(0, 0, 0, 0.2);
|
||||
margin-top: 5.1rem;
|
||||
padding: 3.2rem 0 3.1rem 0;
|
||||
|
||||
.counter {
|
||||
border-right: 1px solid #d9d9d9;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: $primary-color;
|
||||
font-size: 4.8rem;
|
||||
font-weight: 100;
|
||||
line-height: 5.6rem;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #848c91;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 400;
|
||||
line-height: 2.1rem;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import SearchHelp from '../shared/SearchHelp.js';
|
||||
|
||||
const ListHelp = () => {
|
||||
return (
|
||||
<SearchHelp>
|
||||
<ul>
|
||||
<li>
|
||||
<h4>*pisati</h4>
|
||||
<p><em>pisati, <strong>na</strong>pisati, <strong>za</strong>pisati, <strong>pod</strong>pisati…</em></p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>?pisati</h4>
|
||||
<p><em><strong>v</strong>pisati, <strong>o</strong>pisati, <strong>s</strong>pisati…</em></p>
|
||||
</li>
|
||||
</ul>
|
||||
</SearchHelp>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListHelp;
|
||||
@@ -0,0 +1,13 @@
|
||||
import styles from './ListItem.module.scss';
|
||||
|
||||
const ListItem = (props) => {
|
||||
return (
|
||||
<div className={`row ${styles.item}`}>
|
||||
<div className='col'>{props.item.form}</div>
|
||||
<div className='col'>{props.item.lemma}</div>
|
||||
<div className='col'>{props.item.frequency}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,7 @@
|
||||
@import '../../variables';
|
||||
|
||||
.item {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import ListItem from './ListItem';
|
||||
|
||||
import styles from './ListItems.module.scss';
|
||||
|
||||
const ListItems = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<div className={`row ${styles.header}`}>
|
||||
<div className='col'><strong>Termin</strong></div>
|
||||
<div className='col'><strong>Osnovna oblika</strong></div>
|
||||
<div className='col'><strong>Število pojavitev</strong></div>
|
||||
</div>
|
||||
{props.items.map((x, i) => <ListItem key={i} item={x} />)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListItems;
|
||||
@@ -0,0 +1,7 @@
|
||||
@import '../../variables';
|
||||
|
||||
.header {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import closeIcon from '../../assets/close.svg';
|
||||
import exportIcon from '../../assets/export.svg';
|
||||
import styles from './ResultsExport.module.scss';
|
||||
|
||||
const ResultsExport = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
|
||||
const allResults = props.results;
|
||||
const defaultValue = allResults < 100 ? allResults : 100;
|
||||
const maxValue = allResults > 1000 ? 1000 : allResults;
|
||||
|
||||
const [numFirst, setNumFirst] = useState(defaultValue);
|
||||
const [numRandom, setNumRandom] = useState(defaultValue);
|
||||
const [type, setType] = useState('FirstRows');
|
||||
const [isValid, setIsValid] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
let value = type === 'FirstRows' ? numFirst : numRandom;
|
||||
let isValid = value >= 1 && value <= maxValue;
|
||||
setIsValid(isValid);
|
||||
}, [type, numFirst, numRandom, maxValue]);
|
||||
|
||||
const onNumFirstChanged = (e) => {
|
||||
setNumFirst(e.target.value);
|
||||
};
|
||||
|
||||
const onNumRandomChanged = (e) => {
|
||||
setNumRandom(e.target.value);
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
if (isValid) {
|
||||
let value = type === 'FirstRows' ? numFirst : numRandom;
|
||||
props.onConfirm(type, value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.export}>
|
||||
<div className={styles.modal}>
|
||||
<div className={styles.header}>
|
||||
<button className={styles.close} type="button" onClick={props.onClose}><img src={closeIcon} alt='Close' /></button>
|
||||
<img className={styles.icon} src={exportIcon} alt='Export' />
|
||||
<h1>{t('shared.exportTitle')}</h1>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<div className='row'>
|
||||
<div className='col'>{t('shared.exportTotal', { total: allResults })}</div>
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='col'><input type='radio' value='FirstRows' checked={type === 'FirstRows'} onChange={e => setType(e.target.value)} /> {t('shared.exportFirst')} <input type='number' value={numFirst} onChange={onNumFirstChanged} min='1' max={maxValue} /> {t('shared.exportRecords')}</div>
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='col'><input type='radio' value='RandomRows' checked={type === 'RandomRows'} onChange={e => setType(e.target.value)} /> {t('shared.exportRandom')} <input type='number' value={numRandom} onChange={onNumRandomChanged} min='1' max={maxValue} /> {t('shared.exportRecords')}</div>
|
||||
</div>
|
||||
{!isValid && <div className='row'><div className='col'>{t('shared.exportMax', { max: maxValue })}</div></div>}
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<button type="button" onClick={confirm}>{t('shared.export')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResultsExport;
|
||||
@@ -0,0 +1,85 @@
|
||||
@import '../../variables';
|
||||
|
||||
.export {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
||||
.modal {
|
||||
background-color: #ffffff;
|
||||
border-radius: 0.6rem;
|
||||
box-shadow: 0 0.4rem 4rem rgba(0, 0, 0, 0.35);
|
||||
max-width: 70rem;
|
||||
margin: 15% auto;
|
||||
position: relative;
|
||||
width: auto;
|
||||
|
||||
.header {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 0.6rem 0.6rem 0 0;
|
||||
padding: 2.4rem 2.1rem 2.3rem 2.1rem;
|
||||
|
||||
.close {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
position: absolute;
|
||||
top: 2.4rem;
|
||||
right: 2.1rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: block;
|
||||
height: 3.4rem;
|
||||
margin: 4.2rem auto 2.2rem auto;
|
||||
width: 3.4rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: $primary-color;
|
||||
font-size: 3.6rem;
|
||||
font-weight: 300;
|
||||
line-height: 4.2rem;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 2.8rem 9.5rem 0 9.5rem;
|
||||
|
||||
:global(.row) {
|
||||
margin-bottom: 1.6rem;
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #b6bec4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.actions {
|
||||
padding: 5.9rem 2.1rem 3.9rem 2.1rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
button {
|
||||
background-color: $primary-color;
|
||||
box-shadow: 0 0.4rem 0.4rem rgba(0, 0, 0, 0.12);
|
||||
border: none;
|
||||
border-radius: 0.6rem;
|
||||
color: #ffffff;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 400;
|
||||
line-height: 2.1rem;
|
||||
padding: 1rem 6rem 1rem 6rem;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import exportIcon from '../../assets/export.svg';
|
||||
import styles from './ResultsHeader.module.scss';
|
||||
|
||||
const ResultsHeader = (props) => {
|
||||
return (
|
||||
<div className={`row ${styles.resultsHeader}`}>
|
||||
<div className='col'><h1>{props.query}</h1></div>
|
||||
<div className='col text-end'><button type='button' className='btn btn-link' onClick={props.onExport}><img src={exportIcon} alt='Export' /></button></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResultsHeader;
|
||||
@@ -0,0 +1,10 @@
|
||||
@import '../../variables';
|
||||
|
||||
.resultsHeader {
|
||||
h1 {
|
||||
color: $primary-color;
|
||||
font-size: 3.6rem;
|
||||
font-weight: 400;
|
||||
line-height: 4.2rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import useSearch from '../../hooks/use-search';
|
||||
import styles from './ResultsPager.module.scss';
|
||||
|
||||
const ResultsPager = (props) => {
|
||||
const pageSize = 20;
|
||||
const offset = props.offset;
|
||||
const total = props.total;
|
||||
const totalPages = Math.ceil(total / pageSize);
|
||||
const currentPage = Math.floor(offset / pageSize) + 1;
|
||||
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
const search = useSearch();
|
||||
|
||||
const renderPreviousPage = () => {
|
||||
const className = currentPage <= 1 ? 'disabled' : null;
|
||||
return renderPage(currentPage - 1, '<<', className);
|
||||
};
|
||||
|
||||
const renderFirstPage = () => {
|
||||
const className = currentPage === 1 ? 'active' : null;
|
||||
return renderPage(1, '1', className);
|
||||
};
|
||||
|
||||
const renderCurrentPage = () => {
|
||||
return renderPage(currentPage, currentPage, 'active');
|
||||
};
|
||||
|
||||
const renderLastPage = () => {
|
||||
const className = currentPage === totalPages ? 'active' : null;
|
||||
return renderPage(totalPages, totalPages, className);
|
||||
};
|
||||
|
||||
const renderNextPage = () => {
|
||||
const className = currentPage >= totalPages ? 'disabled' : null;
|
||||
return renderPage(currentPage + 1, '>>', className);
|
||||
};
|
||||
|
||||
const renderPage = (page, title, className) => {
|
||||
const link = search.getPagerLink(page);
|
||||
return (
|
||||
<Link className={styles[className]} to={link}>{title}</Link>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`row align-items-center ${styles.pager}`}>
|
||||
<div className='col'>{t('shared.searchRecords', { start: offset + 1, end: offset + pageSize, total: total })}</div>
|
||||
<div className='col'>
|
||||
<div className={`${styles.pages} float-end`}>
|
||||
{renderPreviousPage()}
|
||||
{currentPage > 1 && renderFirstPage()}
|
||||
{renderCurrentPage()}
|
||||
{currentPage < totalPages && renderLastPage()}
|
||||
{renderNextPage()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export default ResultsPager;
|
||||
@@ -0,0 +1,32 @@
|
||||
@import '../../variables';
|
||||
|
||||
.pager {
|
||||
border-bottom: 2px solid $border-color;
|
||||
padding-bottom: 1.1rem;
|
||||
margin-bottom: 2.2rem;
|
||||
|
||||
.pages {
|
||||
display: inline-block;
|
||||
|
||||
a {
|
||||
color: $text-color;
|
||||
display: inline-block;
|
||||
padding: 1rem;
|
||||
text-decoration: none;
|
||||
|
||||
&.active {
|
||||
background-color: #b6bec3;
|
||||
border-radius: 0.4rem;
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $text-color-secondary;
|
||||
cursor: auto;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import SearchDropdown from "./SearchDropdown";
|
||||
import HistoryItem from "./HistoryItem";
|
||||
import styles from './History.module.scss';
|
||||
import useHistory from "../../hooks/use-history";
|
||||
|
||||
const History = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
|
||||
const source = props.source;
|
||||
|
||||
return (
|
||||
<SearchDropdown>
|
||||
<div className={styles.history}>
|
||||
<h3>{t('shared.searchHistory')}</h3>
|
||||
<ul className={styles.historyList}>
|
||||
{history.getHistory(props.source).map((x, i) => <HistoryItem key={i} source={source} query={x.query} />)}
|
||||
</ul>
|
||||
</div>
|
||||
</SearchDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default History;
|
||||
@@ -0,0 +1,18 @@
|
||||
@import '../../variables';
|
||||
|
||||
.history {
|
||||
padding: 0 5rem 4.9rem 3.8rem;
|
||||
|
||||
h3 {
|
||||
color: $primary-color;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 2.8rem;
|
||||
margin-top: 1.9rem;
|
||||
}
|
||||
|
||||
ul.historyList {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import useSearch from '../../hooks/use-search';
|
||||
|
||||
import styles from './HistoryItem.module.scss';
|
||||
|
||||
const HistoryItem = (props) => {
|
||||
const search = useSearch();
|
||||
const source = props.source;
|
||||
|
||||
return (
|
||||
<li className={styles.historyListItem}>
|
||||
<Link to={search.getSearchLink(source, props.query)}>{props.query}</Link>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
export default HistoryItem;
|
||||
@@ -0,0 +1,12 @@
|
||||
@import '../../variables';
|
||||
|
||||
li.historyListItem {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 0.8rem;
|
||||
padding-bottom: 0.8rem;
|
||||
|
||||
a {
|
||||
color: $text-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import styles from './SearchDropdown.module.scss';
|
||||
|
||||
const SearchDropdown = (props) => {
|
||||
return (
|
||||
<div className={styles.dropdown}>
|
||||
<div className={styles.dropdownContent}>
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SearchDropdown;
|
||||
@@ -0,0 +1,13 @@
|
||||
.dropdown {
|
||||
position: relative;
|
||||
|
||||
.dropdownContent {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 0 0 0.6rem 0.6rem;
|
||||
box-shadow: 0 0.4rem 1.2rem rgba(0, 0, 0, 0.25);
|
||||
padding: 1.6rem;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import SearchDropdown from './../shared/SearchDropdown.js';
|
||||
import styles from './SearchHelp.module.scss';
|
||||
|
||||
const SearchHelp = (props) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<SearchDropdown>
|
||||
<div className={styles.help}>
|
||||
<h3>{t('shared.searchHelp')}</h3>
|
||||
{props.children}
|
||||
</div>
|
||||
</SearchDropdown>
|
||||
)
|
||||
};
|
||||
|
||||
export default SearchHelp;
|
||||
@@ -0,0 +1,36 @@
|
||||
@import '../../variables';
|
||||
|
||||
.help {
|
||||
padding: 0 5rem 4.9rem 3.8rem;
|
||||
|
||||
h3 {
|
||||
color: $primary-color;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 2.8rem;
|
||||
margin-top: 1.9rem;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid $border-color;
|
||||
margin-bottom: 2.8rem;
|
||||
padding-bottom: 2.6rem;
|
||||
|
||||
h4 {
|
||||
color: $primary-color;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $text-color;
|
||||
font-size: 1.6rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||