formatted

This commit is contained in:
Amirhossein Mahmoodi
2024-07-09 13:58:13 +03:30
parent 863bdaca95
commit bc73725138
82 changed files with 2206 additions and 3082 deletions

View File

@@ -1,3 +1,3 @@
{ {
"extends": "next/core-web-vitals" "extends": ["next/core-web-vitals","prettier"]
} }

12
.prettierrc Normal file
View File

@@ -0,0 +1,12 @@
{
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"endOfLine": "crlf"
}

View File

@@ -1,485 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = crlf
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 120
tab_width = 4
ij_continuation_indent_size = 4
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = true
ij_smart_tabs = false
ij_visual_guides = none
ij_wrap_on_typing = false
[*.css]
ij_css_align_closing_brace_with_properties = false
ij_css_blank_lines_around_nested_selector = 1
ij_css_blank_lines_between_blocks = 1
ij_css_block_comment_add_space = false
ij_css_brace_placement = end_of_line
ij_css_enforce_quotes_on_format = false
ij_css_hex_color_long_format = false
ij_css_hex_color_lower_case = false
ij_css_hex_color_short_format = false
ij_css_hex_color_upper_case = false
ij_css_keep_blank_lines_in_code = 2
ij_css_keep_indents_on_empty_lines = false
ij_css_keep_single_line_blocks = false
ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_css_space_after_colon = true
ij_css_space_before_opening_brace = true
ij_css_use_double_quotes = true
ij_css_value_alignment = do_not_align
[*.sass]
indent_size = 2
ij_sass_align_closing_brace_with_properties = false
ij_sass_blank_lines_around_nested_selector = 1
ij_sass_blank_lines_between_blocks = 1
ij_sass_brace_placement = 0
ij_sass_enforce_quotes_on_format = false
ij_sass_hex_color_long_format = false
ij_sass_hex_color_lower_case = false
ij_sass_hex_color_short_format = false
ij_sass_hex_color_upper_case = false
ij_sass_keep_blank_lines_in_code = 2
ij_sass_keep_indents_on_empty_lines = false
ij_sass_keep_single_line_blocks = false
ij_sass_line_comment_add_space = false
ij_sass_line_comment_at_first_column = false
ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_sass_space_after_colon = true
ij_sass_space_before_opening_brace = true
ij_sass_use_double_quotes = true
ij_sass_value_alignment = 0
[*.scss]
indent_size = 2
ij_scss_align_closing_brace_with_properties = false
ij_scss_blank_lines_around_nested_selector = 1
ij_scss_blank_lines_between_blocks = 1
ij_scss_block_comment_add_space = false
ij_scss_brace_placement = 0
ij_scss_enforce_quotes_on_format = false
ij_scss_hex_color_long_format = false
ij_scss_hex_color_lower_case = false
ij_scss_hex_color_short_format = false
ij_scss_hex_color_upper_case = false
ij_scss_keep_blank_lines_in_code = 2
ij_scss_keep_indents_on_empty_lines = false
ij_scss_keep_single_line_blocks = false
ij_scss_line_comment_add_space = false
ij_scss_line_comment_at_first_column = false
ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_scss_space_after_colon = true
ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
ij_scss_value_alignment = 0
[{*.ats,*.cts,*.mts,*.ts}]
ij_continuation_indent_size = 4
ij_typescript_align_imports = false
ij_typescript_align_multiline_array_initializer_expression = false
ij_typescript_align_multiline_binary_operation = false
ij_typescript_align_multiline_chained_methods = false
ij_typescript_align_multiline_extends_list = false
ij_typescript_align_multiline_for = true
ij_typescript_align_multiline_parameters = true
ij_typescript_align_multiline_parameters_in_calls = false
ij_typescript_align_multiline_ternary_operation = false
ij_typescript_align_object_properties = 0
ij_typescript_align_union_types = false
ij_typescript_align_var_statements = 0
ij_typescript_array_initializer_new_line_after_left_brace = false
ij_typescript_array_initializer_right_brace_on_new_line = false
ij_typescript_array_initializer_wrap = off
ij_typescript_assignment_wrap = off
ij_typescript_binary_operation_sign_on_next_line = false
ij_typescript_binary_operation_wrap = off
ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_typescript_blank_lines_after_imports = 1
ij_typescript_blank_lines_around_class = 1
ij_typescript_blank_lines_around_field = 0
ij_typescript_blank_lines_around_field_in_interface = 0
ij_typescript_blank_lines_around_function = 1
ij_typescript_blank_lines_around_method = 1
ij_typescript_blank_lines_around_method_in_interface = 1
ij_typescript_block_brace_style = end_of_line
ij_typescript_block_comment_add_space = false
ij_typescript_block_comment_at_first_column = true
ij_typescript_call_parameters_new_line_after_left_paren = false
ij_typescript_call_parameters_right_paren_on_new_line = false
ij_typescript_call_parameters_wrap = off
ij_typescript_catch_on_new_line = false
ij_typescript_chained_call_dot_on_new_line = true
ij_typescript_class_brace_style = end_of_line
ij_typescript_comma_on_new_line = false
ij_typescript_do_while_brace_force = never
ij_typescript_else_on_new_line = false
ij_typescript_enforce_trailing_comma = keep
ij_typescript_enum_constants_wrap = on_every_item
ij_typescript_extends_keyword_wrap = off
ij_typescript_extends_list_wrap = off
ij_typescript_field_prefix = _
ij_typescript_file_name_style = relaxed
ij_typescript_finally_on_new_line = false
ij_typescript_for_brace_force = never
ij_typescript_for_statement_new_line_after_left_paren = false
ij_typescript_for_statement_right_paren_on_new_line = false
ij_typescript_for_statement_wrap = off
ij_typescript_force_quote_style = false
ij_typescript_force_semicolon_style = false
ij_typescript_function_expression_brace_style = end_of_line
ij_typescript_if_brace_force = never
ij_typescript_import_merge_members = global
ij_typescript_import_prefer_absolute_path = global
ij_typescript_import_sort_members = true
ij_typescript_import_sort_module_name = false
ij_typescript_import_use_node_resolution = true
ij_typescript_imports_wrap = on_every_item
ij_typescript_indent_case_from_switch = true
ij_typescript_indent_chained_calls = true
ij_typescript_indent_package_children = 0
ij_typescript_jsdoc_include_types = false
ij_typescript_jsx_attribute_value = braces
ij_typescript_keep_blank_lines_in_code = 2
ij_typescript_keep_first_column_comment = true
ij_typescript_keep_indents_on_empty_lines = false
ij_typescript_keep_line_breaks = true
ij_typescript_keep_simple_blocks_in_one_line = false
ij_typescript_keep_simple_methods_in_one_line = false
ij_typescript_line_comment_add_space = true
ij_typescript_line_comment_at_first_column = false
ij_typescript_method_brace_style = end_of_line
ij_typescript_method_call_chain_wrap = off
ij_typescript_method_parameters_new_line_after_left_paren = false
ij_typescript_method_parameters_right_paren_on_new_line = false
ij_typescript_method_parameters_wrap = off
ij_typescript_object_literal_wrap = on_every_item
ij_typescript_object_types_wrap = on_every_item
ij_typescript_parentheses_expression_new_line_after_left_paren = false
ij_typescript_parentheses_expression_right_paren_on_new_line = false
ij_typescript_place_assignment_sign_on_next_line = false
ij_typescript_prefer_as_type_cast = false
ij_typescript_prefer_explicit_types_function_expression_returns = false
ij_typescript_prefer_explicit_types_function_returns = false
ij_typescript_prefer_explicit_types_vars_fields = false
ij_typescript_prefer_parameters_wrap = false
ij_typescript_reformat_c_style_comments = false
ij_typescript_space_after_colon = true
ij_typescript_space_after_comma = true
ij_typescript_space_after_dots_in_rest_parameter = false
ij_typescript_space_after_generator_mult = true
ij_typescript_space_after_property_colon = true
ij_typescript_space_after_quest = true
ij_typescript_space_after_type_colon = true
ij_typescript_space_after_unary_not = false
ij_typescript_space_before_async_arrow_lparen = true
ij_typescript_space_before_catch_keyword = true
ij_typescript_space_before_catch_left_brace = true
ij_typescript_space_before_catch_parentheses = true
ij_typescript_space_before_class_lbrace = true
ij_typescript_space_before_class_left_brace = true
ij_typescript_space_before_colon = true
ij_typescript_space_before_comma = false
ij_typescript_space_before_do_left_brace = true
ij_typescript_space_before_else_keyword = true
ij_typescript_space_before_else_left_brace = true
ij_typescript_space_before_finally_keyword = true
ij_typescript_space_before_finally_left_brace = true
ij_typescript_space_before_for_left_brace = true
ij_typescript_space_before_for_parentheses = true
ij_typescript_space_before_for_semicolon = false
ij_typescript_space_before_function_left_parenth = true
ij_typescript_space_before_generator_mult = false
ij_typescript_space_before_if_left_brace = true
ij_typescript_space_before_if_parentheses = true
ij_typescript_space_before_method_call_parentheses = false
ij_typescript_space_before_method_left_brace = true
ij_typescript_space_before_method_parentheses = false
ij_typescript_space_before_property_colon = false
ij_typescript_space_before_quest = true
ij_typescript_space_before_switch_left_brace = true
ij_typescript_space_before_switch_parentheses = true
ij_typescript_space_before_try_left_brace = true
ij_typescript_space_before_type_colon = false
ij_typescript_space_before_unary_not = false
ij_typescript_space_before_while_keyword = true
ij_typescript_space_before_while_left_brace = true
ij_typescript_space_before_while_parentheses = true
ij_typescript_spaces_around_additive_operators = true
ij_typescript_spaces_around_arrow_function_operator = true
ij_typescript_spaces_around_assignment_operators = true
ij_typescript_spaces_around_bitwise_operators = true
ij_typescript_spaces_around_equality_operators = true
ij_typescript_spaces_around_logical_operators = true
ij_typescript_spaces_around_multiplicative_operators = true
ij_typescript_spaces_around_relational_operators = true
ij_typescript_spaces_around_shift_operators = true
ij_typescript_spaces_around_unary_operator = false
ij_typescript_spaces_within_array_initializer_brackets = false
ij_typescript_spaces_within_brackets = false
ij_typescript_spaces_within_catch_parentheses = false
ij_typescript_spaces_within_for_parentheses = false
ij_typescript_spaces_within_if_parentheses = false
ij_typescript_spaces_within_imports = false
ij_typescript_spaces_within_interpolation_expressions = false
ij_typescript_spaces_within_method_call_parentheses = false
ij_typescript_spaces_within_method_parentheses = false
ij_typescript_spaces_within_object_literal_braces = false
ij_typescript_spaces_within_object_type_braces = true
ij_typescript_spaces_within_parentheses = false
ij_typescript_spaces_within_switch_parentheses = false
ij_typescript_spaces_within_type_assertion = false
ij_typescript_spaces_within_union_types = true
ij_typescript_spaces_within_while_parentheses = false
ij_typescript_special_else_if_treatment = true
ij_typescript_ternary_operation_signs_on_next_line = false
ij_typescript_ternary_operation_wrap = off
ij_typescript_union_types_wrap = on_every_item
ij_typescript_use_chained_calls_group_indents = false
ij_typescript_use_double_quotes = true
ij_typescript_use_explicit_js_extension = auto
ij_typescript_use_path_mapping = always
ij_typescript_use_public_modifier = false
ij_typescript_use_semicolon_after_statement = true
ij_typescript_var_declaration_wrap = normal
ij_typescript_while_brace_force = never
ij_typescript_while_on_new_line = false
ij_typescript_wrap_comments = false
[{*.cjs,*.js}]
ij_continuation_indent_size = 4
ij_javascript_align_imports = false
ij_javascript_align_multiline_array_initializer_expression = false
ij_javascript_align_multiline_binary_operation = false
ij_javascript_align_multiline_chained_methods = false
ij_javascript_align_multiline_extends_list = false
ij_javascript_align_multiline_for = true
ij_javascript_align_multiline_parameters = true
ij_javascript_align_multiline_parameters_in_calls = false
ij_javascript_align_multiline_ternary_operation = false
ij_javascript_align_object_properties = 0
ij_javascript_align_union_types = false
ij_javascript_align_var_statements = 0
ij_javascript_array_initializer_new_line_after_left_brace = false
ij_javascript_array_initializer_right_brace_on_new_line = false
ij_javascript_array_initializer_wrap = off
ij_javascript_assignment_wrap = off
ij_javascript_binary_operation_sign_on_next_line = false
ij_javascript_binary_operation_wrap = off
ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_javascript_blank_lines_after_imports = 1
ij_javascript_blank_lines_around_class = 1
ij_javascript_blank_lines_around_field = 0
ij_javascript_blank_lines_around_function = 1
ij_javascript_blank_lines_around_method = 1
ij_javascript_block_brace_style = end_of_line
ij_javascript_block_comment_add_space = false
ij_javascript_block_comment_at_first_column = true
ij_javascript_call_parameters_new_line_after_left_paren = false
ij_javascript_call_parameters_right_paren_on_new_line = false
ij_javascript_call_parameters_wrap = off
ij_javascript_catch_on_new_line = false
ij_javascript_chained_call_dot_on_new_line = true
ij_javascript_class_brace_style = end_of_line
ij_javascript_comma_on_new_line = false
ij_javascript_do_while_brace_force = never
ij_javascript_else_on_new_line = false
ij_javascript_enforce_trailing_comma = keep
ij_javascript_extends_keyword_wrap = off
ij_javascript_extends_list_wrap = off
ij_javascript_field_prefix = _
ij_javascript_file_name_style = relaxed
ij_javascript_finally_on_new_line = false
ij_javascript_for_brace_force = never
ij_javascript_for_statement_new_line_after_left_paren = false
ij_javascript_for_statement_right_paren_on_new_line = false
ij_javascript_for_statement_wrap = off
ij_javascript_force_quote_style = false
ij_javascript_force_semicolon_style = false
ij_javascript_function_expression_brace_style = end_of_line
ij_javascript_if_brace_force = never
ij_javascript_import_merge_members = global
ij_javascript_import_prefer_absolute_path = global
ij_javascript_import_sort_members = true
ij_javascript_import_sort_module_name = false
ij_javascript_import_use_node_resolution = true
ij_javascript_imports_wrap = on_every_item
ij_javascript_indent_case_from_switch = true
ij_javascript_indent_chained_calls = true
ij_javascript_indent_package_children = 0
ij_javascript_jsx_attribute_value = braces
ij_javascript_keep_blank_lines_in_code = 2
ij_javascript_keep_first_column_comment = true
ij_javascript_keep_indents_on_empty_lines = false
ij_javascript_keep_line_breaks = true
ij_javascript_keep_simple_blocks_in_one_line = false
ij_javascript_keep_simple_methods_in_one_line = false
ij_javascript_line_comment_add_space = true
ij_javascript_line_comment_at_first_column = false
ij_javascript_method_brace_style = end_of_line
ij_javascript_method_call_chain_wrap = off
ij_javascript_method_parameters_new_line_after_left_paren = false
ij_javascript_method_parameters_right_paren_on_new_line = false
ij_javascript_method_parameters_wrap = off
ij_javascript_object_literal_wrap = on_every_item
ij_javascript_object_types_wrap = on_every_item
ij_javascript_parentheses_expression_new_line_after_left_paren = false
ij_javascript_parentheses_expression_right_paren_on_new_line = false
ij_javascript_place_assignment_sign_on_next_line = false
ij_javascript_prefer_as_type_cast = false
ij_javascript_prefer_explicit_types_function_expression_returns = false
ij_javascript_prefer_explicit_types_function_returns = false
ij_javascript_prefer_explicit_types_vars_fields = false
ij_javascript_prefer_parameters_wrap = false
ij_javascript_reformat_c_style_comments = false
ij_javascript_space_after_colon = true
ij_javascript_space_after_comma = true
ij_javascript_space_after_dots_in_rest_parameter = false
ij_javascript_space_after_generator_mult = true
ij_javascript_space_after_property_colon = true
ij_javascript_space_after_quest = true
ij_javascript_space_after_type_colon = true
ij_javascript_space_after_unary_not = false
ij_javascript_space_before_async_arrow_lparen = true
ij_javascript_space_before_catch_keyword = true
ij_javascript_space_before_catch_left_brace = true
ij_javascript_space_before_catch_parentheses = true
ij_javascript_space_before_class_lbrace = true
ij_javascript_space_before_class_left_brace = true
ij_javascript_space_before_colon = true
ij_javascript_space_before_comma = false
ij_javascript_space_before_do_left_brace = true
ij_javascript_space_before_else_keyword = true
ij_javascript_space_before_else_left_brace = true
ij_javascript_space_before_finally_keyword = true
ij_javascript_space_before_finally_left_brace = true
ij_javascript_space_before_for_left_brace = true
ij_javascript_space_before_for_parentheses = true
ij_javascript_space_before_for_semicolon = false
ij_javascript_space_before_function_left_parenth = true
ij_javascript_space_before_generator_mult = false
ij_javascript_space_before_if_left_brace = true
ij_javascript_space_before_if_parentheses = true
ij_javascript_space_before_method_call_parentheses = false
ij_javascript_space_before_method_left_brace = true
ij_javascript_space_before_method_parentheses = false
ij_javascript_space_before_property_colon = false
ij_javascript_space_before_quest = true
ij_javascript_space_before_switch_left_brace = true
ij_javascript_space_before_switch_parentheses = true
ij_javascript_space_before_try_left_brace = true
ij_javascript_space_before_type_colon = false
ij_javascript_space_before_unary_not = false
ij_javascript_space_before_while_keyword = true
ij_javascript_space_before_while_left_brace = true
ij_javascript_space_before_while_parentheses = true
ij_javascript_spaces_around_additive_operators = true
ij_javascript_spaces_around_arrow_function_operator = true
ij_javascript_spaces_around_assignment_operators = true
ij_javascript_spaces_around_bitwise_operators = true
ij_javascript_spaces_around_equality_operators = true
ij_javascript_spaces_around_logical_operators = true
ij_javascript_spaces_around_multiplicative_operators = true
ij_javascript_spaces_around_relational_operators = true
ij_javascript_spaces_around_shift_operators = true
ij_javascript_spaces_around_unary_operator = false
ij_javascript_spaces_within_array_initializer_brackets = false
ij_javascript_spaces_within_brackets = false
ij_javascript_spaces_within_catch_parentheses = false
ij_javascript_spaces_within_for_parentheses = false
ij_javascript_spaces_within_if_parentheses = false
ij_javascript_spaces_within_imports = false
ij_javascript_spaces_within_interpolation_expressions = false
ij_javascript_spaces_within_method_call_parentheses = false
ij_javascript_spaces_within_method_parentheses = false
ij_javascript_spaces_within_object_literal_braces = false
ij_javascript_spaces_within_object_type_braces = true
ij_javascript_spaces_within_parentheses = false
ij_javascript_spaces_within_switch_parentheses = false
ij_javascript_spaces_within_type_assertion = false
ij_javascript_spaces_within_union_types = true
ij_javascript_spaces_within_while_parentheses = false
ij_javascript_special_else_if_treatment = true
ij_javascript_ternary_operation_signs_on_next_line = false
ij_javascript_ternary_operation_wrap = off
ij_javascript_union_types_wrap = on_every_item
ij_javascript_use_chained_calls_group_indents = false
ij_javascript_use_double_quotes = true
ij_javascript_use_explicit_js_extension = auto
ij_javascript_use_path_mapping = always
ij_javascript_use_public_modifier = false
ij_javascript_use_semicolon_after_statement = true
ij_javascript_var_declaration_wrap = normal
ij_javascript_while_brace_force = never
ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false
[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
indent_size = 2
ij_json_array_wrapping = split_into_lines
ij_json_keep_blank_lines_in_code = 0
ij_json_keep_indents_on_empty_lines = false
ij_json_keep_line_breaks = true
ij_json_keep_trailing_comma = false
ij_json_object_wrapping = split_into_lines
ij_json_property_alignment = do_not_align
ij_json_space_after_colon = true
ij_json_space_after_comma = true
ij_json_space_before_colon = false
ij_json_space_before_comma = false
ij_json_spaces_within_braces = false
ij_json_spaces_within_brackets = false
ij_json_wrap_long_lines = false
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
ij_html_align_attributes = true
ij_html_align_text = false
ij_html_attribute_wrap = normal
ij_html_block_comment_add_space = false
ij_html_block_comment_at_first_column = true
ij_html_do_not_align_children_of_min_lines = 0
ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
ij_html_enforce_quotes = false
ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
ij_html_keep_blank_lines = 2
ij_html_keep_indents_on_empty_lines = false
ij_html_keep_line_breaks = true
ij_html_keep_line_breaks_in_text = true
ij_html_keep_whitespaces = false
ij_html_keep_whitespaces_inside = span, pre, textarea
ij_html_line_comment_at_first_column = true
ij_html_new_line_after_last_attribute = never
ij_html_new_line_before_first_attribute = never
ij_html_quote_style = double
ij_html_remove_new_line_before_tags = br
ij_html_space_after_tag_name = false
ij_html_space_around_equality_in_attribute = false
ij_html_space_inside_empty_tag = false
ij_html_text_wrap = normal
[{*.markdown,*.md}]
ij_markdown_force_one_space_after_blockquote_symbol = true
ij_markdown_force_one_space_after_header_symbol = true
ij_markdown_force_one_space_after_list_bullet = true
ij_markdown_force_one_space_between_words = true
ij_markdown_format_tables = true
ij_markdown_insert_quote_arrows_on_wrap = true
ij_markdown_keep_indents_on_empty_lines = false
ij_markdown_keep_line_breaks_inside_text_blocks = true
ij_markdown_max_lines_around_block_elements = 1
ij_markdown_max_lines_around_header = 1
ij_markdown_max_lines_between_paragraphs = 1
ij_markdown_min_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
ij_markdown_wrap_text_if_long = true
ij_markdown_wrap_text_inside_blockquotes = true

View File

@@ -6,7 +6,8 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,html,css,scss}\""
}, },
"dependencies": { "dependencies": {
"@emotion/cache": "^11.11.0", "@emotion/cache": "^11.11.0",
@@ -35,6 +36,8 @@
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8", "eslint": "^8",
"eslint-config-next": "14.1.0" "eslint-config-next": "14.1.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "^3.3.2"
} }
} }

View File

@@ -1,29 +1,33 @@
'use client' "use client";
import { Button } from "@mui/material" import { Button } from "@mui/material";
import axios from "axios" import axios from "axios";
const Page = () => { const Page = () => {
const handler = () => { const handler = () => {
try { try {
axios.get('https://rms.witel.ir/test_login?username=witel', { withCredentials: true }) axios.get("https://rms.witel.ir/test_login?username=witel", {
withCredentials: true,
});
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
} };
const handler2 = () => { const handler2 = () => {
try { try {
const res = axios.get('https://rms.witel.ir/webapi/user/get-permission', { withCredentials: true }) const res = axios.get("https://rms.witel.ir/webapi/user/get-permission", {
withCredentials: true,
});
console.log(res); console.log(res);
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
} };
return ( return (
<> <>
<Button onClick={handler}>login</Button> <Button onClick={handler}>login</Button>
<Button onClick={handler2}>check</Button> <Button onClick={handler2}>check</Button>
</> </>
) );
} };
export default Page export default Page;

View File

@@ -1,19 +1,17 @@
import { Box, Stack } from "@mui/material"; import { Box, Stack } from "@mui/material";
import HeaderWithLogo from "@/components/layouts/dashboard/headerWithLogo"; import HeaderWithLogo from "@/components/layouts/dashboard/headerWithLogo";
import HeaderWithSidebar from "@/components/layouts/dashboard/headerWithSidebar"; import HeaderWithSidebar from "@/components/layouts/dashboard/headerWithSidebar";
import 'react-toastify/dist/ReactToastify.css'; import "react-toastify/dist/ReactToastify.css";
const Template = ({ children }) => { const Template = ({ children }) => {
return ( return (
<Stack> <Stack>
<HeaderWithLogo /> <HeaderWithLogo />
<Box> <Box>
<HeaderWithSidebar> <HeaderWithSidebar>{children}</HeaderWithSidebar>
{children}
</HeaderWithSidebar>
</Box> </Box>
</Stack> </Stack>
) );
} };
export default Template export default Template;

View File

@@ -1,14 +1,12 @@
import WithAuthMiddleware from "@/core/middlewares/withAuth" import WithAuthMiddleware from "@/core/middlewares/withAuth";
import { AuthProvider } from "@/lib/contexts/auth" import { AuthProvider } from "@/lib/contexts/auth";
const Layout = ({ children }) => { const Layout = ({ children }) => {
return ( return (
<AuthProvider> <AuthProvider>
<WithAuthMiddleware> <WithAuthMiddleware>{children}</WithAuthMiddleware>
{children}
</WithAuthMiddleware>
</AuthProvider> </AuthProvider>
) );
} };
export default Layout export default Layout;

View File

@@ -1,3 +1,3 @@
export default function Default() { export default function Default() {
return null return null;
} }

View File

@@ -1,17 +1,15 @@
import { TableSettingProvider } from "@/lib/contexts/tableSetting"; import { TableSettingProvider } from "@/lib/contexts/tableSetting";
export const metadata = { export const metadata = {
title: 'سامانه جامع راهداری', title: "سامانه جامع راهداری",
} };
export default function RootLayout({ children }) { export default function RootLayout({ children }) {
return ( return (
<html lang="fa" dir={'rtl'}> <html lang="fa" dir={"rtl"}>
<body style={{ height: '100vh' }}> <body style={{ height: "100vh" }}>
<TableSettingProvider> <TableSettingProvider>{children}</TableSettingProvider>
{children}
</TableSettingProvider>
</body> </body>
</html> </html>
) );
} }

View File

@@ -1,51 +1,57 @@
'use client' "use client";
import { GET_LOGIN_ROUTE } from "@/core/utils/routes" import { GET_LOGIN_ROUTE } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest" import useRequest from "@/lib/hooks/useRequest";
import { Button, Stack, Typography, Zoom } from "@mui/material" import { Button, Stack, Typography, Zoom } from "@mui/material";
import Link from "next/link" import Link from "next/link";
import { useEffect, useState } from "react" import { useEffect, useState } from "react";
const Page = () => { const Page = ({ searchParams }) => {
const [login, setLogin] = useState(0) const { username } = searchParams;
const request = useRequest() const [login, setLogin] = useState(0);
const request = useRequest();
useEffect(() => { useEffect(() => {
const login = async () => { const login = async () => {
try { try {
const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) await request(`${GET_LOGIN_ROUTE}?username=${username}`);
setLogin(1) setLogin(1);
} catch (error) { } catch (error) {
setLogin(2) setLogin(2);
} }
} };
login() login();
}, []) }, []);
const retry = async () => { const retry = async () => {
setLogin(0) setLogin(0);
try { try {
const res = await request(`${GET_LOGIN_ROUTE}?username=witel`) await request(`${GET_LOGIN_ROUTE}?username=${username}`);
setLogin(1) setLogin(1);
} catch (error) { } catch (error) {
setLogin(2) setLogin(2);
} }
} };
return ( return (
<Stack alignItems={'center'} justifyContent={'center'} sx={{ height: '100%' }} spacing={2}> <Stack alignItems={"center"} justifyContent={"center"} sx={{ height: "100%" }} spacing={2}>
<Typography variant="h5"> <Typography variant="h5">
{login === 0 ? 'درحال دریافت مجوز برای ارتباط با سرور...' : login === 1 ? 'ارتباط با سرور برقرار شد.' : 'ارتباط با سرور برقرار نشد. مشکلی وجود دارد.'} {login === 0
? "درحال دریافت مجوز برای ارتباط با سرور..."
: login === 1
? "ارتباط با سرور برقرار شد."
: "ارتباط با سرور برقرار نشد. مشکلی وجود دارد."}
</Typography> </Typography>
<Zoom in={login === 1}> <Zoom in={login === 1}>
<Button component={Link} href="/">ورود به سامانه</Button> <Button component={Link} href="/">
ورود به سامانه
</Button>
</Zoom> </Zoom>
<Zoom in={login === 2}> <Zoom in={login === 2}>
<Button onClick={retry}>تلاش مجدد</Button> <Button onClick={retry}>تلاش مجدد</Button>
</Zoom> </Zoom>
</Stack> </Stack>
) );
} };
export default Page export default Page;

View File

@@ -1,8 +1,8 @@
import { redirect } from "next/navigation" import { redirect } from "next/navigation";
function Page() { function Page() {
redirect('/dashboard', 'replace') redirect("/dashboard", "replace");
return null return null;
} }
export default Page export default Page;

View File

@@ -15,7 +15,7 @@ const Template = ({ children }) => {
<ToastContainer rtl containerId="request_data" /> <ToastContainer rtl containerId="request_data" />
</ThemeProvider> </ThemeProvider>
</AppRouterCacheProvider> </AppRouterCacheProvider>
) );
} };
export default Template export default Template;

View File

@@ -1,22 +1,10 @@
import {Button} from "@mui/material"; import { Button } from "@mui/material";
const Toolbar = ({columns}) => { const Toolbar = ({ columns }) => {
return ( return (
<> <>
<Button>add something</Button> <Button>add something</Button>
</> </>
) );
} };
export default Toolbar export default Toolbar;

View File

@@ -1,149 +1,128 @@
'use client' "use client";
import DataTable from "@/core/components/DataTable"; import DataTable from "@/core/components/DataTable";
import {useMemo} from "react"; import { useMemo } from "react";
function HomeComponent() { function HomeComponent() {
const columns = useMemo( const columns = useMemo(
() => [ () => [
{ {
accessorKey: 'fullname', accessorKey: "fullname",
header: 'نام کامل', header: "نام کامل",
id: "fullname", id: "fullname",
columns: [ columns: [
{ {
accessorKey: 'name.firstName', accessorKey: "name.firstName",
header: 'نام', header: "نام",
id: "firstName", id: "firstName",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "text", datatype: "text",
filterFn: "contains", filterFn: "contains",
enableClickToCopy: true, enableClickToCopy: true,
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals", "contains"],
"equals",
"notEquals",
"contains"
],
}, },
{ {
accessorKey: 'name.lastName', accessorKey: "name.lastName",
header: 'نام خانوادگی', header: "نام خانوادگی",
id: "lastName", id: "lastName",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "text", datatype: "text",
filterFn: "equals", filterFn: "equals",
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals", "contains"],
"equals",
"notEquals",
"contains"
],
}, },
], ],
}, },
{ {
accessorKey: 'address', accessorKey: "address",
header: 'آدرس', header: "آدرس",
id: "address", id: "address",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "text", datatype: "text",
filterFn: "notEquals", filterFn: "notEquals",
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals", "contains"],
"equals",
"notEquals",
"contains"
],
}, },
{ {
accessorKey: 'city', accessorKey: "city",
header: 'شهر', header: "شهر",
id: "city", id: "city",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "text", datatype: "text",
filterFn: "equals", filterFn: "equals",
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals", "contains", "lessThan", "greaterThan", "fuzzy"],
"equals",
"notEquals",
"contains",
"lessThan",
"greaterThan",
"fuzzy"
],
}, },
{ {
accessorKey: 'state', accessorKey: "state",
header: 'وضعیت', header: "وضعیت",
id: "state", id: "state",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "text", datatype: "text",
filterFn: "contains", filterFn: "contains",
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals", "contains"],
"equals",
"notEquals",
"contains"
],
}, },
{ {
accessorKey: 'price', accessorKey: "price",
header: 'محدوده', header: "محدوده",
id: "price", id: "price",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "numeric", datatype: "numeric",
filterFn: "equals", filterFn: "equals",
columnFilterModeOptions: [ columnFilterModeOptions: ["equals", "notEquals"],
"equals",
"notEquals",
],
}, },
{ {
accessorKey: 'created_at', accessorKey: "created_at",
header: 'تاریخ ساخت', header: "تاریخ ساخت",
id: "created_at", id: "created_at",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "date", datatype: "date",
filterFn: "between", filterFn: "between",
}, },
{ {
accessorKey: 'updated_at', accessorKey: "updated_at",
header: 'تاریخ بروزرسانی', header: "تاریخ بروزرسانی",
id: "updated_at", id: "updated_at",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "date", datatype: "date",
filterFn: "equals", filterFn: "equals",
}, },
{ {
accessorKey: 'company', accessorKey: "company",
header: 'نام شرکت', header: "نام شرکت",
id: "company", id: "company",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "numeric", datatype: "numeric",
filterFn: "equals", filterFn: "equals",
columnSelectOption: [ columnSelectOption: [
{value: 1, label: "وایتل"}, { value: 1, label: "وایتل" },
{value: 2, label: "اسنپ"}, { value: 2, label: "اسنپ" },
{value: 3, label: "تپسی"} { value: 3, label: "تپسی" },
], ],
}, },
{ {
accessorKey: 'area', accessorKey: "area",
header: 'منطقه', header: "منطقه",
id: "area", id: "area",
enableColumnFilter: true, enableColumnFilter: true,
datatype: "array", datatype: "array",
filterFn: "equals", filterFn: "equals",
columnSelectOption: [ columnSelectOption: [
{value: 1, label: "وایتل"}, { value: 1, label: "وایتل" },
{value: 2, label: "اسنپ"}, { value: 2, label: "اسنپ" },
{value: 3, label: "تپسی"} { value: 3, label: "تپسی" },
], ],
}, },
], ],
[], []
); );
return ( return (
<> <>
<DataTable columns={columns} table_url={"api"} user_id={0} page_name={'testPage'} table_name={'testTable'}/> <DataTable
columns={columns}
table_url={"api"}
user_id={0}
page_name={"testPage"}
table_name={"testTable"}
/>
</> </>
); );
} }

View File

@@ -3,38 +3,25 @@ import { Stack, Typography } from "@mui/material";
import Image from "next/image"; import Image from "next/image";
const HeaderBottom = () => { const HeaderBottom = () => {
return ( return (
<Stack <Stack
sx={{ sx={{
px: 2, px: 2,
py: 1, py: 1,
background: (theme) => theme.palette.primary2.main, background: (theme) => theme.palette.primary2.main,
}} }}
spacing={4} spacing={4}
alignItems={"center"} alignItems={"center"}
direction={"row"} direction={"row"}
>
<Image
alt=""
priority
src={"/images/rmsLogo.svg"}
width={65}
height={71}
/>
<Stack alignItems={"center"} spacing={1}>
<Typography
variant="h5"
sx={{ color: (theme) => theme.palette.primary2.contrastText }}
> >
سامانه جامع راهداری <Image alt="" priority src={"/images/rmsLogo.svg"} width={65} height={71} />
</Typography> <Stack alignItems={"center"} spacing={1}>
<Typography <Typography variant="h5" sx={{ color: (theme) => theme.palette.primary2.contrastText }}>
sx={{ color: (theme) => theme.palette.primary2.contrastText }} سامانه جامع راهداری
> </Typography>
rms.rmto.ir <Typography sx={{ color: (theme) => theme.palette.primary2.contrastText }}>rms.rmto.ir</Typography>
</Typography> </Stack>
</Stack> </Stack>
</Stack> );
);
}; };
export default HeaderBottom; export default HeaderBottom;

View File

@@ -2,16 +2,10 @@ import { Stack } from "@mui/material";
import Image from "next/image"; import Image from "next/image";
const HeaderTop = () => { const HeaderTop = () => {
return ( return (
<Stack sx={{ p: 2 }}> <Stack sx={{ p: 2 }}>
<Image <Image alt="" priority src={"/images/headerLogo.png"} width={190} height={44} />
alt="" </Stack>
priority );
src={"/images/headerLogo.png"}
width={190}
height={44}
/>
</Stack>
);
}; };
export default HeaderTop; export default HeaderTop;

View File

@@ -3,11 +3,11 @@ import HeaderTop from "./HaederTop";
import HeaderBottom from "./HaederBottom"; import HeaderBottom from "./HaederBottom";
const HeaderWithLogo = () => { const HeaderWithLogo = () => {
return ( return (
<Stack> <Stack>
<HeaderTop /> <HeaderTop />
<HeaderBottom /> <HeaderBottom />
</Stack> </Stack>
); );
}; };
export default HeaderWithLogo; export default HeaderWithLogo;

View File

@@ -1,4 +1,4 @@
const HeaderMenu = () => { const HeaderMenu = () => {
return <>منو</>; return <>منو</>;
}; };
export default HeaderMenu; export default HeaderMenu;

View File

@@ -9,108 +9,102 @@ import HeaderMenu from "./HeaderMenu";
const drawerWidth = 300; const drawerWidth = 300;
const Main = styled(Paper, { shouldForwardProp: (prop) => prop !== "open" })( const Main = styled(Paper, { shouldForwardProp: (prop) => prop !== "open" })(({ theme, open }) => ({
({ theme, open }) => ({
flexGrow: 1, flexGrow: 1,
transition: theme.transitions.create("margin", { transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen, duration: theme.transitions.duration.leavingScreen,
}), }),
marginLeft: `-${drawerWidth}px`, marginLeft: `-${drawerWidth}px`,
...(open && { ...(open && {
transition: theme.transitions.create("margin", { transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut, easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen, duration: theme.transitions.duration.enteringScreen,
}), }),
marginLeft: 0, marginLeft: 0,
}), }),
}) }));
);
const AppBar = styled(MuiAppBar, { const AppBar = styled(MuiAppBar, {
shouldForwardProp: (prop) => prop !== "open", shouldForwardProp: (prop) => prop !== "open",
})(({ theme, open }) => ({ })(({ theme, open }) => ({
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(["margin", "width"], { transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut, easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen, duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}), }),
}),
})); }));
const DrawerHeader = styled("div")(({ theme }) => ({ const DrawerHeader = styled("div")(({ theme }) => ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
padding: theme.spacing(0, 1), padding: theme.spacing(0, 1),
...theme.mixins.toolbar, ...theme.mixins.toolbar,
justifyContent: "flex-end", justifyContent: "flex-end",
})); }));
const HeaderWithSidebar = ({ children }) => { const HeaderWithSidebar = ({ children }) => {
const [open, setOpen] = useState(true); const [open, setOpen] = useState(true);
const handleDrawerOpen = () => { const handleDrawerOpen = () => {
setOpen(true); setOpen(true);
}; };
const handleDrawerClose = () => { const handleDrawerClose = () => {
setOpen(false); setOpen(false);
}; };
return ( return (
<Box sx={{ display: "flex" }}> <Box sx={{ display: "flex" }}>
<AppBar <AppBar sx={{ position: "fixed", top: "unset" }} elevation={0} open={open}>
sx={{ position: "fixed", top: "unset" }} <Toolbar variant="dense">
elevation={0} <IconButton
open={open} color="inherit"
> aria-label="open drawer"
<Toolbar variant="dense"> onClick={handleDrawerOpen}
<IconButton edge="start"
color="inherit" sx={{ mr: 2, ...(open && { display: "none" }) }}
aria-label="open drawer" >
onClick={handleDrawerOpen} <MenuIcon />
edge="start" </IconButton>
sx={{ mr: 2, ...(open && { display: "none" }) }} <Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}>
> <HeaderMenu />
<MenuIcon /> </Box>
</IconButton> </Toolbar>
<Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}> </AppBar>
<HeaderMenu /> <Drawer
</Box> sx={{
</Toolbar> width: drawerWidth,
</AppBar> flexShrink: 0,
<Drawer "& .MuiDrawer-paper": {
sx={{ width: drawerWidth,
width: drawerWidth, boxSizing: "border-box",
flexShrink: 0, borderTop: 1,
"& .MuiDrawer-paper": { borderTopColor: "divider",
width: drawerWidth, top: "unset",
boxSizing: "border-box", },
borderTop: 1, }}
borderTopColor: "divider", variant="persistent"
top: "unset", anchor="left"
}, open={open}
}} >
variant="persistent" <DrawerHeader>
anchor="left" <IconButton onClick={handleDrawerClose}>
open={open} <ChevronRightIcon />
> </IconButton>
<DrawerHeader> </DrawerHeader>
<IconButton onClick={handleDrawerClose}> <SidebarMenu />
<ChevronRightIcon /> </Drawer>
</IconButton> <Main elevation={0} open={open}>
</DrawerHeader> <DrawerHeader />
<SidebarMenu /> {children}
</Drawer> </Main>
<Main elevation={0} open={open}> </Box>
<DrawerHeader /> );
{children}
</Main>
</Box>
);
}; };
export default HeaderWithSidebar; export default HeaderWithSidebar;

View File

@@ -1,91 +1,96 @@
import DataTable_Paper from "./table/Paper"; import DataTable_Paper from "./table/Paper";
import {useMaterialReactTable} from "material-react-table"; import { useMaterialReactTable } from "material-react-table";
import {FA_DATATABLE_LOCALIZATION} from "./localization/fa/datatable"; import { FA_DATATABLE_LOCALIZATION } from "./localization/fa/datatable";
import useTableSetting from "@/lib/hooks/useTableSetting"; import useTableSetting from "@/lib/hooks/useTableSetting";
import {flattenArrayOfObjects} from "@/core/utils/flattenArrayOfObjects"; import { flattenArrayOfObjects } from "@/core/utils/flattenArrayOfObjects";
import Toolbar from "@/components/home/Toolbar"; import Toolbar from "@/components/home/Toolbar";
import useDataTable from "@/lib/hooks/useDataTable"; import useDataTable from "@/lib/hooks/useDataTable";
import {useMemo, useState} from "react"; import { useMemo, useState } from "react";
const data = [ const data = [
{ {
name: { name: {
firstName: 'امین', firstName: "امین",
lastName: 'قاسمپور', lastName: "قاسمپور",
}, },
address: 'فلان جا', address: "فلان جا",
city: 'تهران', city: "تهران",
state: 'بررسی شده', state: "بررسی شده",
price: '20', price: "20",
updated_at: '2024/05/02', updated_at: "2024/05/02",
company: 'همراه اول', company: "همراه اول",
area: 'منطقه 5', area: "منطقه 5",
}, },
{ {
name: { name: {
firstName: 'امیر حسین', firstName: "امیر حسین",
lastName: 'محمودی', lastName: "محمودی",
}, },
address: 'فلان جا', address: "فلان جا",
city: 'تهران', city: "تهران",
state: 'تکمیل شده', state: "تکمیل شده",
price: '27', price: "27",
updated_at: '2024/05/02', updated_at: "2024/05/02",
company: 'وایتل', company: "وایتل",
area: 'منطقه 27', area: "منطقه 27",
}, },
{ {
name: { name: {
firstName: 'یاسمن', firstName: "یاسمن",
lastName: 'علی اکبری', lastName: "علی اکبری",
}, },
address: 'فلان جا', address: "فلان جا",
city: 'شیراز', city: "شیراز",
state: 'بررسی شده', state: "بررسی شده",
price: '32', price: "32",
updated_at: '2024/05/02', updated_at: "2024/05/02",
company: 'ایرانسل', company: "ایرانسل",
area: 'منطقه 23', area: "منطقه 23",
}, },
{ {
name: { name: {
firstName: 'حمیدرضا', firstName: "حمیدرضا",
lastName: 'رنجبرپور', lastName: "رنجبرپور",
}, },
address: 'فلان جا', address: "فلان جا",
city: 'اصفهان', city: "اصفهان",
state: 'بررسی شده', state: "بررسی شده",
price: '45', price: "45",
updated_at: '2024/05/02', updated_at: "2024/05/02",
company: 'ایرانول', company: "ایرانول",
area: 'منطقه 21', area: "منطقه 21",
}, },
{ {
name: { name: {
firstName: 'محمد', firstName: "محمد",
lastName: 'جلالی', lastName: "جلالی",
}, },
address: 'فلان جا', address: "فلان جا",
city: 'رشت', city: "رشت",
state: 'درحال بررسی', state: "درحال بررسی",
price: '8', price: "8",
updated_at: '2024/05/02', updated_at: "2024/05/02",
company: 'فیلیمو', company: "فیلیمو",
area: 'منطقه 8', area: "منطقه 8",
}, },
]; ];
const DataTable_Main = (props) => { const DataTable_Main = (props) => {
const {filterData} = useDataTable(); const { filterData } = useDataTable();
const {table_url, user_id, page_name, table_name, columns, initialStateProps} = props const { table_url, user_id, page_name, table_name, columns, initialStateProps } = props;
const flatColumns = flattenArrayOfObjects(columns, 'columns') const flatColumns = flattenArrayOfObjects(columns, "columns");
const {settingStore, hideAction, sortAction} = useTableSetting(); const { settingStore, hideAction, sortAction } = useTableSetting();
const [pagination, setPagination] = useState({pageIndex: 0, pageSize: 10}); const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
const filters = Object.keys(filterData) const filters = Object.keys(filterData)
.map(key => { .map((key) => {
const value = filterData[key].value; const value = filterData[key].value;
if (value !== "" && if (
!(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) { value !== "" &&
!(
Array.isArray(value) &&
(value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === ""))
)
) {
return filterData[key]; return filterData[key];
} }
}) })
@@ -98,7 +103,7 @@ const DataTable_Main = (props) => {
params.set("start", `${pagination.pageIndex * pagination.pageSize}`); params.set("start", `${pagination.pageIndex * pagination.pageSize}`);
params.set("size", pagination.pageSize); params.set("size", pagination.pageSize);
params.set("filters", JSON.stringify(finalFilters ?? [])); params.set("filters", JSON.stringify(finalFilters ?? []));
params.set("sorting", JSON.stringify(settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] ?? [])); params.set("sorting", JSON.stringify(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] ?? []));
return `${table_url}?${params}`; return `${table_url}?${params}`;
}, [table_url, finalFilters, pagination, columns]); }, [table_url, finalFilters, pagination, columns]);
@@ -107,52 +112,52 @@ const DataTable_Main = (props) => {
hideAction(user_id, page_name, table_name, settingValue, flatColumns); hideAction(user_id, page_name, table_name, settingValue, flatColumns);
}; };
const onSortingChange = (event) => { const onSortingChange = (event) => {
const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || []); const settingValue = event(settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || []);
sortAction(user_id, page_name, table_name, settingValue, flatColumns); sortAction(user_id, page_name, table_name, settingValue, flatColumns);
} };
const table = useMaterialReactTable({ const table = useMaterialReactTable({
localization: FA_DATATABLE_LOCALIZATION, localization: FA_DATATABLE_LOCALIZATION,
columns, columns,
data: data, data: data,
// manualSorting: true, // manualSorting: true,
renderTopToolbarCustomActions: ({table}) => (<> renderTopToolbarCustomActions: ({ table }) => (
<Toolbar <>
columns={flatColumns} <Toolbar columns={flatColumns} />
/> </>
</>), ),
initialState: { initialState: {
density: 'compact', density: "compact",
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [],
...initialStateProps ...initialStateProps,
}, },
state: { state: {
columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.['hides'], columnVisibility: settingStore?.[user_id]?.[page_name]?.[table_name]?.["hides"],
sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.['sorts'] || [], sorting: settingStore?.[user_id]?.[page_name]?.[table_name]?.["sorts"] || [],
pagination pagination,
}, },
muiTableHeadProps: { muiTableHeadProps: {
sx: { sx: {
borderTop: "1px solid #e1e1e1", borderTop: "1px solid #e1e1e1",
borderBottom: "2px solid #e1e1e1", borderBottom: "2px solid #e1e1e1",
} },
}, },
muiTableHeadCellProps: { muiTableHeadCellProps: {
sx: { sx: {
color: "primary.main", color: "primary.main",
borderLeft: "1px solid #e1e1e1", borderLeft: "1px solid #e1e1e1",
"&:first-of-type": { "&:first-of-type": {
borderLeft: "unset" borderLeft: "unset",
} },
}, },
}, },
muiTableBodyCellProps: { muiTableBodyCellProps: {
sx: { sx: {
borderLeft: "1px solid #e1e1e1", borderLeft: "1px solid #e1e1e1",
"&:first-of-type": { "&:first-of-type": {
borderLeft: "unset" borderLeft: "unset",
} },
}, },
}, },
manualFiltering: true, manualFiltering: true,
@@ -161,14 +166,18 @@ const DataTable_Main = (props) => {
manualSorting: true, manualSorting: true,
onColumnVisibilityChange: onColumnVisibilityChange, onColumnVisibilityChange: onColumnVisibilityChange,
onSortingChange: onSortingChange, onSortingChange: onSortingChange,
...props ...props,
}) });
return <DataTable_Paper table={table} columns={flatColumns} user_id={user_id} page_name={page_name} return (
table_name={table_name}/>; <DataTable_Paper
table={table}
columns={flatColumns}
user_id={user_id}
page_name={page_name}
table_name={table_name}
/>
);
}; };
export default DataTable_Main; export default DataTable_Main;

View File

@@ -4,11 +4,7 @@ import { useMRT_RowVirtualizer, useMRT_Rows } from "material-react-table";
import { memo, useMemo } from "react"; import { memo, useMemo } from "react";
import DataTable_TableBodyRow, { Memo_DataTable_TableBodyRow } from "./TableBodyRow"; import DataTable_TableBodyRow, { Memo_DataTable_TableBodyRow } from "./TableBodyRow";
const DataTable_TableBody = ({ const DataTable_TableBody = ({ columnVirtualizer, table, ...rest }) => {
columnVirtualizer,
table,
...rest
}) => {
const { const {
getBottomRows, getBottomRows,
getIsSomeRowsPinned, getIsSomeRowsPinned,
@@ -35,12 +31,8 @@ const DataTable_TableBody = ({
...rest, ...rest,
}; };
const tableHeadHeight = const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0;
((enableStickyHeader || isFullScreen) && const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
tableHeadRef.current?.clientHeight) ||
0;
const tableFooterHeight =
(enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
const pinnedRowIds = useMemo(() => { const pinnedRowIds = useMemo(() => {
if (!rowPinning.bottom?.length && !rowPinning.top?.length) return []; if (!rowPinning.bottom?.length && !rowPinning.top?.length) return [];
@@ -63,67 +55,63 @@ const DataTable_TableBody = ({
return ( return (
<> <>
{!rowPinningDisplayMode?.includes('sticky') && {!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("top") && (
getIsSomeRowsPinned('top') && ( <TableBody
<TableBody {...tableBodyProps}
{...tableBodyProps} sx={(theme) => ({
sx={(theme) => ({ display: layoutMode?.startsWith("grid") ? "grid" : undefined,
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, position: "sticky",
position: 'sticky', top: tableHeadHeight - 1,
top: tableHeadHeight - 1, zIndex: 1,
zIndex: 1, ...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)), })}
})} >
> {getTopRows().map((row, staticRowIndex) => {
{getTopRows().map((row, staticRowIndex) => { const props = {
const props = { ...commonRowProps,
...commonRowProps, row,
row, staticRowIndex,
staticRowIndex, };
}; return memoMode === "rows" ? (
return memoMode === 'rows' ? ( <Memo_DataTable_TableBodyRow key={row.id} {...props} />
<Memo_DataTable_TableBodyRow key={row.id} {...props} /> ) : (
) : ( <DataTable_TableBodyRow key={row.id} {...props} />
<DataTable_TableBodyRow key={row.id} {...props} /> );
); })}
})} </TableBody>
</TableBody> )}
)}
<TableBody <TableBody
{...tableBodyProps} {...tableBodyProps}
sx={(theme) => ({ sx={(theme) => ({
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
height: rowVirtualizer height: rowVirtualizer ? `${rowVirtualizer.getTotalSize()}px` : undefined,
? `${rowVirtualizer.getTotalSize()}px` minHeight: !rows.length ? "100px" : undefined,
: undefined, position: "relative",
minHeight: !rows.length ? '100px' : undefined, ...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
position: 'relative',
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)),
})} })}
> >
{tableBodyProps?.children ?? {tableBodyProps?.children ??
(!rows.length ? ( (!rows.length ? (
<tr <tr
style={{ style={{
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
}} }}
> >
<td <td
colSpan={table.getVisibleLeafColumns().length} colSpan={table.getVisibleLeafColumns().length}
style={{ style={{
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
}} }}
> >
{renderEmptyRowsFallback?.({ table }) ?? ( {renderEmptyRowsFallback?.({ table }) ?? (
<Typography <Typography
sx={{ sx={{
color: 'text.secondary', color: "text.secondary",
fontStyle: 'italic', fontStyle: "italic",
maxWidth: `min(100vw, ${tablePaperRef.current?.clientWidth ?? 360 maxWidth: `min(100vw, ${tablePaperRef.current?.clientWidth ?? 360}px)`,
}px)`, py: "2rem",
py: '2rem', textAlign: "center",
textAlign: 'center', width: "100%",
width: '100%',
}} }}
> >
{globalFilter || columnFilters.length {globalFilter || columnFilters.length
@@ -155,12 +143,10 @@ const DataTable_TableBody = ({
row, row,
rowVirtualizer, rowVirtualizer,
staticRowIndex, staticRowIndex,
virtualRow: rowVirtualizer virtualRow: rowVirtualizer ? rowOrVirtualRow : undefined,
? (rowOrVirtualRow)
: undefined,
}; };
const key = `${row.id}-${row.index}`; const key = `${row.id}-${row.index}`;
return memoMode === 'rows' ? ( return memoMode === "rows" ? (
<Memo_DataTable_TableBodyRow key={key} {...props} /> <Memo_DataTable_TableBodyRow key={key} {...props} />
) : ( ) : (
<DataTable_TableBodyRow key={key} {...props} /> <DataTable_TableBodyRow key={key} {...props} />
@@ -169,39 +155,37 @@ const DataTable_TableBody = ({
</> </>
))} ))}
</TableBody> </TableBody>
{!rowPinningDisplayMode?.includes('sticky') && {!rowPinningDisplayMode?.includes("sticky") && getIsSomeRowsPinned("bottom") && (
getIsSomeRowsPinned('bottom') && ( <TableBody
<TableBody {...tableBodyProps}
{...tableBodyProps} sx={(theme) => ({
sx={(theme) => ({ bottom: tableFooterHeight - 1,
bottom: tableFooterHeight - 1, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, position: "sticky",
position: 'sticky', zIndex: 1,
zIndex: 1, ...parseFromValuesOrFunc(tableBodyProps?.sx, theme),
...(parseFromValuesOrFunc(tableBodyProps?.sx, theme)), })}
})} >
> {getBottomRows().map((row, staticRowIndex) => {
{getBottomRows().map((row, staticRowIndex) => { const props = {
const props = { ...commonRowProps,
...commonRowProps, row,
row, staticRowIndex,
staticRowIndex, };
}; return memoMode === "rows" ? (
return memoMode === 'rows' ? ( <Memo_DataTable_TableBodyRow key={row.id} {...props} />
<Memo_DataTable_TableBodyRow key={row.id} {...props} /> ) : (
) : ( <DataTable_TableBodyRow key={row.id} {...props} />
<DataTable_TableBodyRow key={row.id} {...props} /> );
); })}
})} </TableBody>
</TableBody> )}
)}
</> </>
); );
};
} export default DataTable_TableBody;
export default DataTable_TableBody
export const Memo_DataTable_TableBody = memo( export const Memo_DataTable_TableBody = memo(
DataTable_TableBody, DataTable_TableBody,
(prev, next) => prev.table.options.data === next.table.options.data, (prev, next) => prev.table.options.data === next.table.options.data
); );

View File

@@ -7,15 +7,7 @@ const { useState, useEffect, useMemo, memo } = require("react");
const { default: DataTable_CopyButton } = require("../buttons/CopyButton"); const { default: DataTable_CopyButton } = require("../buttons/CopyButton");
const { default: DataTable_TableBodyCellValue } = require("./TableBodyCellValue"); const { default: DataTable_TableBodyCellValue } = require("./TableBodyCellValue");
const DataTable_TableBodyCell = ({ const DataTable_TableBodyCell = ({ cell, numRows, rowRef, staticColumnIndex, staticRowIndex, table, ...rest }) => {
cell,
numRows,
rowRef,
staticColumnIndex,
staticRowIndex,
table,
...rest
}) => {
const theme = useTheme(); const theme = useTheme();
const { const {
getState, getState,
@@ -73,9 +65,7 @@ const DataTable_TableBodyCell = ({
if ((!isLoading && !showSkeletons) || skeletonWidth !== 100) return; if ((!isLoading && !showSkeletons) || skeletonWidth !== 100) return;
const size = column.getSize(); const size = column.getSize();
setSkeletonWidth( setSkeletonWidth(
columnDefType === 'display' columnDefType === "display" ? size / 2 : Math.round(Math.random() * (size - size / 3) + size / 3)
? size / 2
: Math.round(Math.random() * (size - size / 3) + size / 3),
); );
}, [isLoading, showSkeletons]); }, [isLoading, showSkeletons]);
@@ -88,77 +78,55 @@ const DataTable_TableBodyCell = ({
const isLastColumn = column.getIsLastColumn(); const isLastColumn = column.getIsLastColumn();
const isLastRow = numRows && staticRowIndex === numRows - 1; const isLastRow = numRows && staticRowIndex === numRows - 1;
const isResizingColumn = columnSizingInfo.isResizingColumn === column.id; const isResizingColumn = columnSizingInfo.isResizingColumn === column.id;
const showResizeBorder = const showResizeBorder = isResizingColumn && columnResizeMode === "onChange";
isResizingColumn && columnResizeMode === 'onChange';
const borderStyle = showResizeBorder const borderStyle = showResizeBorder
? `2px solid ${draggingBorderColor} !important` ? `2px solid ${draggingBorderColor} !important`
: isDraggingColumn || isDraggingRow : isDraggingColumn || isDraggingRow
? `1px dashed ${theme.palette.grey[500]} !important` ? `1px dashed ${theme.palette.grey[500]} !important`
: isHoveredColumn || isHoveredRow || isResizingColumn : isHoveredColumn || isHoveredRow || isResizingColumn
? `2px dashed ${draggingBorderColor} !important` ? `2px dashed ${draggingBorderColor} !important`
: undefined; : undefined;
if (showResizeBorder) { if (showResizeBorder) {
return columnResizeDirection === 'ltr' return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
? { borderRight: borderStyle }
: { borderLeft: borderStyle };
} }
return borderStyle return borderStyle
? { ? {
borderBottom: borderBottom:
isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) isDraggingRow || isHoveredRow || (isLastRow && !isResizingColumn) ? borderStyle : undefined,
? borderStyle borderLeft:
: undefined, isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isFirstColumn)
borderLeft: ? borderStyle
isDraggingColumn || : undefined,
isHoveredColumn || borderRight:
((isDraggingRow || isHoveredRow) && isFirstColumn) isDraggingColumn || isHoveredColumn || ((isDraggingRow || isHoveredRow) && isLastColumn)
? borderStyle ? borderStyle
: undefined, : undefined,
borderRight: borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined,
isDraggingColumn || }
isHoveredColumn ||
((isDraggingRow || isHoveredRow) && isLastColumn)
? borderStyle
: undefined,
borderTop: isDraggingRow || isHoveredRow ? borderStyle : undefined,
}
: undefined; : undefined;
}, [ }, [columnSizingInfo.isResizingColumn, draggingColumn, draggingRow, hoveredColumn, hoveredRow, staticRowIndex]);
columnSizingInfo.isResizingColumn,
draggingColumn,
draggingRow,
hoveredColumn,
hoveredRow,
staticRowIndex,
]);
const isColumnPinned = const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned();
enableColumnPinning &&
columnDef.columnDefType !== 'group' &&
column.getIsPinned();
const isEditable = isCellEditable({ cell, table }); const isEditable = isCellEditable({ cell, table });
const isEditing = const isEditing =
isEditable && isEditable &&
!['custom', 'modal'].includes(editDisplayMode) && !["custom", "modal"].includes(editDisplayMode) &&
(editDisplayMode === 'table' || (editDisplayMode === "table" || editingRow?.id === row.id || editingCell?.id === cell.id) &&
editingRow?.id === row.id ||
editingCell?.id === cell.id) &&
!row.getIsGrouped(); !row.getIsGrouped();
const isCreating = const isCreating = isEditable && createDisplayMode === "row" && creatingRow?.id === row.id;
isEditable && createDisplayMode === 'row' && creatingRow?.id === row.id;
const showClickToCopyButton = const showClickToCopyButton =
(parseFromValuesOrFunc(enableClickToCopy, cell) === true || (parseFromValuesOrFunc(enableClickToCopy, cell) === true ||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === true) && parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === true) &&
!['context-menu', false].includes( !["context-menu", false].includes(
// @ts-ignore // @ts-ignore
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell), parseFromValuesOrFunc(columnDef.enableClickToCopy, cell)
); );
const isRightClickable = parseFromValuesOrFunc(enableCellActions, cell); const isRightClickable = parseFromValuesOrFunc(enableCellActions, cell);
@@ -175,13 +143,11 @@ const DataTable_TableBodyCell = ({
const handleDragEnter = (e) => { const handleDragEnter = (e) => {
tableCellProps?.onDragEnter?.(e); tableCellProps?.onDragEnter?.(e);
if (enableGrouping && hoveredColumn?.id === 'drop-zone') { if (enableGrouping && hoveredColumn?.id === "drop-zone") {
setHoveredColumn(null); setHoveredColumn(null);
} }
if (enableColumnOrdering && draggingColumn) { if (enableColumnOrdering && draggingColumn) {
setHoveredColumn( setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null);
columnDef.enableColumnOrdering !== false ? column : null,
);
} }
}; };
@@ -210,43 +176,39 @@ const DataTable_TableBodyCell = ({
onDragEnter={handleDragEnter} onDragEnter={handleDragEnter}
onDragOver={handleDragOver} onDragOver={handleDragOver}
sx={(theme) => ({ sx={(theme) => ({
'&:hover': { "&:hover": {
outline: outline:
actionCell?.id === cell.id || actionCell?.id === cell.id ||
(editDisplayMode === 'cell' && isEditable) || (editDisplayMode === "cell" && isEditable) ||
(editDisplayMode === 'table' && (isCreating || isEditing)) (editDisplayMode === "table" && (isCreating || isEditing))
? `1px solid ${theme.palette.grey[500]}` ? `1px solid ${theme.palette.grey[500]}`
: undefined, : undefined,
textOverflow: 'clip', textOverflow: "clip",
}, },
alignItems: layoutMode?.startsWith('grid') ? 'center' : undefined, alignItems: layoutMode?.startsWith("grid") ? "center" : undefined,
cursor: isRightClickable cursor: isRightClickable
? 'context-menu' ? "context-menu"
: isEditable && editDisplayMode === 'cell' : isEditable && editDisplayMode === "cell"
? 'pointer' ? "pointer"
: 'inherit', : "inherit",
outline: outline: actionCell?.id === cell.id ? `1px solid ${theme.palette.grey[500]}` : undefined,
actionCell?.id === cell.id outlineOffset: "-1px",
? `1px solid ${theme.palette.grey[500]}` overflow: "hidden",
: undefined,
outlineOffset: '-1px',
overflow: 'hidden',
p: p:
density === 'compact' density === "compact"
? columnDefType === 'display' ? columnDefType === "display"
? '0 0.5rem' ? "0 0.5rem"
: '0.5rem' : "0.5rem"
: density === 'comfortable' : density === "comfortable"
? columnDefType === 'display' ? columnDefType === "display"
? '0.5rem 0.75rem' ? "0.5rem 0.75rem"
: '1rem' : "1rem"
: columnDefType === 'display' : columnDefType === "display"
? '1rem 1.25rem' ? "1rem 1.25rem"
: '1.5rem', : "1.5rem",
textOverflow: columnDefType !== 'display' ? 'ellipsis' : undefined, textOverflow: columnDefType !== "display" ? "ellipsis" : undefined,
whiteSpace: whiteSpace: row.getIsPinned() || density === "compact" ? "nowrap" : "normal",
row.getIsPinned() || density === 'compact' ? 'nowrap' : 'normal',
...getCommonMRTCellStyles({ ...getCommonMRTCellStyles({
column, column,
table, table,
@@ -261,17 +223,10 @@ const DataTable_TableBodyCell = ({
{cell.getIsPlaceholder() ? ( {cell.getIsPlaceholder() ? (
columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null
) : showSkeletons !== false && (isLoading || showSkeletons) ? ( ) : showSkeletons !== false && (isLoading || showSkeletons) ? (
<Skeleton <Skeleton animation="wave" height={20} width={skeletonWidth} {...skeletonProps} />
animation="wave" ) : columnDefType === "display" &&
height={20} (["mrt-row-expand", "mrt-row-numbers", "mrt-row-select"].includes(column.id) ||
width={skeletonWidth} !row.getIsGrouped()) ? (
{...skeletonProps}
/>
) : columnDefType === 'display' &&
(['mrt-row-expand', 'mrt-row-numbers', 'mrt-row-select'].includes(
column.id,
) ||
!row.getIsGrouped()) ? (
columnDef.Cell?.({ columnDef.Cell?.({
cell, cell,
column, column,
@@ -289,18 +244,12 @@ const DataTable_TableBodyCell = ({
) : ( ) : (
<DataTable_TableBodyCellValue {...cellValueProps} /> <DataTable_TableBodyCellValue {...cellValueProps} />
)} )}
{cell.getIsGrouped() && !columnDef.GroupedCell && ( {cell.getIsGrouped() && !columnDef.GroupedCell && <> ({row.subRows?.length})</>}
<> ({row.subRows?.length})</>
)}
</> </>
)} )}
</TableCell> </TableCell>
); );
};
}
export default DataTable_TableBodyCell; export default DataTable_TableBodyCell;
export const Memo_DataTable_TableBodyCell = memo( export const Memo_DataTable_TableBodyCell = memo(DataTable_TableBodyCell, (prev, next) => next.cell === prev.cell);
DataTable_TableBodyCell,
(prev, next) => next.cell === prev.cell,
);

View File

@@ -2,111 +2,102 @@ import { Box } from "@mui/material";
const allowedTypes = ["string", "number"]; const allowedTypes = ["string", "number"];
const DataTable_TableBodyCellValue = ({ const DataTable_TableBodyCellValue = ({ cell, rowRef, staticColumnIndex, staticRowIndex, table }) => {
cell, const {
rowRef, getState,
staticColumnIndex, options: {
staticRowIndex, enableFilterMatchHighlighting,
table, mrtTheme: { matchHighlightColor },
}) => { },
const { } = table;
getState, const { column, row } = cell;
options: { const { columnDef } = column;
enableFilterMatchHighlighting, const { globalFilter, globalFilterFn } = getState();
mrtTheme: { matchHighlightColor }, const filterValue = column.getFilterValue();
},
} = table;
const { column, row } = cell;
const { columnDef } = column;
const { globalFilter, globalFilterFn } = getState();
const filterValue = column.getFilterValue();
let renderedCellValue = let renderedCellValue =
cell.getIsAggregated() && columnDef.AggregatedCell cell.getIsAggregated() && columnDef.AggregatedCell
? columnDef.AggregatedCell({ ? columnDef.AggregatedCell({
cell, cell,
column, column,
row, row,
table, table,
}) })
: row.getIsGrouped() && !cell.getIsGrouped() : row.getIsGrouped() && !cell.getIsGrouped()
? null ? null
: cell.getIsGrouped() && columnDef.GroupedCell : cell.getIsGrouped() && columnDef.GroupedCell
? columnDef.GroupedCell({ ? columnDef.GroupedCell({
cell,
column,
row,
table,
})
: undefined;
const isGroupedValue = renderedCellValue !== undefined;
if (!isGroupedValue) {
renderedCellValue = cell.renderValue();
}
if (
enableFilterMatchHighlighting &&
columnDef.enableFilterMatchHighlighting !== false &&
String(renderedCellValue) &&
allowedTypes.includes(typeof renderedCellValue) &&
((filterValue &&
allowedTypes.includes(typeof filterValue) &&
["autocomplete", "text"].includes(columnDef.filterVariant)) ||
(globalFilter && allowedTypes.includes(typeof globalFilter) && column.getCanGlobalFilter()))
) {
const chunks = highlightWords?.({
matchExactly: (filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy",
query: (filterValue ?? globalFilter ?? "").toString(),
text: renderedCellValue?.toString(),
});
if (chunks?.length > 1 || chunks?.[0]?.match) {
renderedCellValue = (
<span aria-label={renderedCellValue} role="note">
{chunks?.map(({ key, match, text }) => (
<Box
aria-hidden="true"
component="span"
key={key}
sx={
match
? {
backgroundColor: matchHighlightColor,
borderRadius: "2px",
color: (theme) =>
theme.palette.mode === "dark"
? theme.palette.common.white
: theme.palette.common.black,
padding: "2px 1px",
}
: undefined
}
>
{text}
</Box>
)) ?? renderedCellValue}
</span>
);
}
}
if (columnDef.Cell && !isGroupedValue) {
renderedCellValue = columnDef.Cell({
cell, cell,
column, column,
renderedCellValue,
row, row,
rowRef,
staticColumnIndex,
staticRowIndex,
table, table,
}) });
: undefined;
const isGroupedValue = renderedCellValue !== undefined;
if (!isGroupedValue) {
renderedCellValue = cell.renderValue();
}
if (
enableFilterMatchHighlighting &&
columnDef.enableFilterMatchHighlighting !== false &&
String(renderedCellValue) &&
allowedTypes.includes(typeof renderedCellValue) &&
((filterValue &&
allowedTypes.includes(typeof filterValue) &&
["autocomplete", "text"].includes(columnDef.filterVariant)) ||
(globalFilter &&
allowedTypes.includes(typeof globalFilter) &&
column.getCanGlobalFilter()))
) {
const chunks = highlightWords?.({
matchExactly:
(filterValue ? columnDef._filterFn : globalFilterFn) !== "fuzzy",
query: (filterValue ?? globalFilter ?? "").toString(),
text: renderedCellValue?.toString(),
});
if (chunks?.length > 1 || chunks?.[0]?.match) {
renderedCellValue = (
<span aria-label={renderedCellValue} role="note">
{chunks?.map(({ key, match, text }) => (
<Box
aria-hidden="true"
component="span"
key={key}
sx={
match
? {
backgroundColor: matchHighlightColor,
borderRadius: "2px",
color: (theme) =>
theme.palette.mode === "dark"
? theme.palette.common.white
: theme.palette.common.black,
padding: "2px 1px",
}
: undefined
}
>
{text}
</Box>
)) ?? renderedCellValue}
</span>
);
} }
}
if (columnDef.Cell && !isGroupedValue) { return renderedCellValue;
renderedCellValue = columnDef.Cell({
cell,
column,
renderedCellValue,
row,
rowRef,
staticColumnIndex,
staticRowIndex,
table,
});
}
return renderedCellValue;
}; };
export default DataTable_TableBodyCellValue; export default DataTable_TableBodyCellValue;

View File

@@ -28,11 +28,7 @@ const DataTable_TableBodyRow = ({
enableStickyHeader, enableStickyHeader,
layoutMode, layoutMode,
memoMode, memoMode,
mrtTheme: { mrtTheme: { baseBackgroundColor, pinnedRowBackgroundColor, selectedRowBackgroundColor },
baseBackgroundColor,
pinnedRowBackgroundColor,
selectedRowBackgroundColor,
},
muiTableBodyRowProps, muiTableBodyRowProps,
renderDetailPanel, renderDetailPanel,
rowPinningDisplayMode, rowPinningDisplayMode,
@@ -40,21 +36,12 @@ const DataTable_TableBodyRow = ({
refs: { tableFooterRef, tableHeadRef }, refs: { tableFooterRef, tableHeadRef },
setHoveredRow, setHoveredRow,
} = table; } = table;
const { const { density, draggingColumn, draggingRow, editingCell, editingRow, hoveredRow, isFullScreen, rowPinning } =
density, getState();
draggingColumn,
draggingRow,
editingCell,
editingRow,
hoveredRow,
isFullScreen,
rowPinning,
} = getState();
const visibleCells = row.getVisibleCells(); const visibleCells = row.getVisibleCells();
const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {};
columnVirtualizer ?? {};
const isRowSelected = getIsRowSelected({ row, table }); const isRowSelected = getIsRowSelected({ row, table });
const isRowPinned = enableRowPinning && row.getIsPinned(); const isRowPinned = enableRowPinning && row.getIsPinned();
@@ -71,30 +58,17 @@ const DataTable_TableBodyRow = ({
}; };
const [bottomPinnedIndex, topPinnedIndex] = useMemo(() => { const [bottomPinnedIndex, topPinnedIndex] = useMemo(() => {
if ( if (!enableRowPinning || !rowPinningDisplayMode?.includes("sticky") || !pinnedRowIds || !row.getIsPinned())
!enableRowPinning ||
!rowPinningDisplayMode?.includes('sticky') ||
!pinnedRowIds ||
!row.getIsPinned()
)
return []; return [];
return [ return [[...pinnedRowIds].reverse().indexOf(row.id), pinnedRowIds.indexOf(row.id)];
[...pinnedRowIds].reverse().indexOf(row.id),
pinnedRowIds.indexOf(row.id),
];
}, [pinnedRowIds, rowPinning]); }, [pinnedRowIds, rowPinning]);
const tableHeadHeight = const tableHeadHeight = ((enableStickyHeader || isFullScreen) && tableHeadRef.current?.clientHeight) || 0;
((enableStickyHeader || isFullScreen) && const tableFooterHeight = (enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
tableHeadRef.current?.clientHeight) ||
0;
const tableFooterHeight =
(enableStickyFooter && tableFooterRef.current?.clientHeight) || 0;
const sx = parseFromValuesOrFunc(tableRowProps?.sx, theme); const sx = parseFromValuesOrFunc(tableRowProps?.sx, theme);
const defaultRowHeight = const defaultRowHeight = density === "compact" ? 37 : density === "comfortable" ? 53 : 69;
density === 'compact' ? 37 : density === 'comfortable' ? 53 : 69;
const customRowHeight = const customRowHeight =
// @ts-ignore // @ts-ignore
@@ -117,16 +91,16 @@ const DataTable_TableBodyRow = ({
const cellHighlightColor = isRowSelected const cellHighlightColor = isRowSelected
? selectedRowBackgroundColor ? selectedRowBackgroundColor
: isRowPinned : isRowPinned
? pinnedRowBackgroundColor ? pinnedRowBackgroundColor
: undefined; : undefined;
const cellHighlightColorHover = const cellHighlightColorHover =
tableRowProps?.hover !== false tableRowProps?.hover !== false
? isRowSelected ? isRowSelected
? cellHighlightColor ? cellHighlightColor
: theme.palette.mode === 'dark' : theme.palette.mode === "dark"
? `${lighten(baseBackgroundColor, 0.3)}` ? `${lighten(baseBackgroundColor, 0.3)}`
: `${darken(baseBackgroundColor, 0.3)}` : `${darken(baseBackgroundColor, 0.3)}`
: undefined; : undefined;
return ( return (
@@ -146,91 +120,81 @@ const DataTable_TableBodyRow = ({
selected={isRowSelected} selected={isRowSelected}
{...tableRowProps} {...tableRowProps}
style={{ style={{
transform: virtualRow transform: virtualRow ? `translateY(${virtualRow.start}px)` : undefined,
? `translateY(${virtualRow.start}px)`
: undefined,
...tableRowProps?.style, ...tableRowProps?.style,
}} }}
sx={(theme) => ({ sx={(theme) => ({
'&:hover td:after': cellHighlightColorHover "&:hover td:after": cellHighlightColorHover
? { ? {
backgroundColor: alpha(cellHighlightColorHover, 0.3), backgroundColor: alpha(cellHighlightColorHover, 0.3),
...commonCellBeforeAfterStyles, ...commonCellBeforeAfterStyles,
} }
: undefined, : undefined,
backgroundColor: `${baseBackgroundColor} !important`, backgroundColor: `${baseBackgroundColor} !important`,
bottom: bottom:
!virtualRow && bottomPinnedIndex !== undefined && isRowPinned !virtualRow && bottomPinnedIndex !== undefined && isRowPinned
? `${bottomPinnedIndex * rowHeight + ? `${bottomPinnedIndex * rowHeight + (enableStickyFooter ? tableFooterHeight - 1 : 0)}px`
(enableStickyFooter ? tableFooterHeight - 1 : 0)
}px`
: undefined, : undefined,
boxSizing: 'border-box', boxSizing: "border-box",
display: layoutMode?.startsWith('grid') ? 'flex' : undefined, display: layoutMode?.startsWith("grid") ? "flex" : undefined,
opacity: isRowPinned ? 0.97 : isDraggingRow || isHoveredRow ? 0.5 : 1, opacity: isRowPinned ? 0.97 : isDraggingRow || isHoveredRow ? 0.5 : 1,
position: virtualRow position: virtualRow
? 'absolute' ? "absolute"
: rowPinningDisplayMode?.includes('sticky') && isRowPinned : rowPinningDisplayMode?.includes("sticky") && isRowPinned
? 'sticky' ? "sticky"
: 'relative', : "relative",
td: { td: {
...getCommonPinnedCellStyles({ table, theme }), ...getCommonPinnedCellStyles({ table, theme }),
}, },
'td:after': cellHighlightColor "td:after": cellHighlightColor
? { ? {
backgroundColor: cellHighlightColor, backgroundColor: cellHighlightColor,
...commonCellBeforeAfterStyles, ...commonCellBeforeAfterStyles,
} }
: undefined, : undefined,
top: virtualRow top: virtualRow
? 0 ? 0
: topPinnedIndex !== undefined && isRowPinned : topPinnedIndex !== undefined && isRowPinned
? `${topPinnedIndex * rowHeight + ? `${
(enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0) topPinnedIndex * rowHeight +
(enableStickyHeader || isFullScreen ? tableHeadHeight - 1 : 0)
}px` }px`
: undefined, : undefined,
transition: virtualRow ? 'none' : 'all 150ms ease-in-out', transition: virtualRow ? "none" : "all 150ms ease-in-out",
width: '100%', width: "100%",
zIndex: zIndex: rowPinningDisplayMode?.includes("sticky") && isRowPinned ? 2 : 0,
rowPinningDisplayMode?.includes('sticky') && isRowPinned ? 2 : 0, ...sx,
...(sx),
})} })}
> >
{virtualPaddingLeft ? ( {virtualPaddingLeft ? <td style={{ display: "flex", width: virtualPaddingLeft }} /> : null}
<td style={{ display: 'flex', width: virtualPaddingLeft }} /> {(virtualColumns ?? visibleCells).map((cellOrVirtualCell, staticColumnIndex) => {
) : null} let cell = cellOrVirtualCell;
{(virtualColumns ?? visibleCells).map( if (columnVirtualizer) {
(cellOrVirtualCell, staticColumnIndex) => { staticColumnIndex = cellOrVirtualCell.index;
let cell = cellOrVirtualCell; cell = visibleCells[staticColumnIndex];
if (columnVirtualizer) { }
staticColumnIndex = (cellOrVirtualCell).index; const props = {
cell = visibleCells[staticColumnIndex]; cell,
} numRows,
const props = { rowRef,
cell, staticColumnIndex,
numRows, staticRowIndex,
rowRef, table,
staticColumnIndex, };
staticRowIndex, return cell ? (
table, memoMode === "cells" &&
}; cell.column.columnDef.columnDefType === "data" &&
return cell ? ( !draggingColumn &&
memoMode === 'cells' && !draggingRow &&
cell.column.columnDef.columnDefType === 'data' && editingCell?.id !== cell.id &&
!draggingColumn && editingRow?.id !== row.id ? (
!draggingRow && <Memo_DataTable_TableBodyCell key={cell.id} {...props} />
editingCell?.id !== cell.id && ) : (
editingRow?.id !== row.id ? ( <DataTable_TableBodyCell key={cell.id} {...props} />
<Memo_DataTable_TableBodyCell key={cell.id} {...props} /> )
) : ( ) : null;
<DataTable_TableBodyCell key={cell.id} {...props} /> })}
) {virtualPaddingRight ? <td style={{ display: "flex", width: virtualPaddingRight }} /> : null}
) : null;
},
)}
{virtualPaddingRight ? (
<td style={{ display: 'flex', width: virtualPaddingRight }} />
) : null}
</TableRow> </TableRow>
{renderDetailPanel && !row.getIsGrouped() && ( {renderDetailPanel && !row.getIsGrouped() && (
<DataTable_TableDetailPanel <DataTable_TableDetailPanel
@@ -244,11 +208,10 @@ const DataTable_TableBodyRow = ({
)} )}
</> </>
); );
} };
export default DataTable_TableBodyRow export default DataTable_TableBodyRow;
export const Memo_DataTable_TableBodyRow = memo( export const Memo_DataTable_TableBodyRow = memo(
DataTable_TableBodyRow, DataTable_TableBodyRow,
(prev, next) => (prev, next) => prev.row === next.row && prev.staticRowIndex === next.staticRowIndex
prev.row === next.row && prev.staticRowIndex === next.staticRowIndex, );
);

View File

@@ -23,7 +23,6 @@ const DataTable_TableDetailPanel = ({
} = table; } = table;
const { isLoading } = getState(); const { isLoading } = getState();
const tableRowProps = parseFromValuesOrFunc(muiTableBodyRowProps, { const tableRowProps = parseFromValuesOrFunc(muiTableBodyRowProps, {
isDetailPanel: true, isDetailPanel: true,
row, row,
@@ -52,16 +51,12 @@ const DataTable_TableDetailPanel = ({
}} }}
{...tableRowProps} {...tableRowProps}
sx={(theme) => ({ sx={(theme) => ({
display: layoutMode?.startsWith('grid') ? 'flex' : undefined, display: layoutMode?.startsWith("grid") ? "flex" : undefined,
position: virtualRow ? 'absolute' : undefined, position: virtualRow ? "absolute" : undefined,
top: virtualRow top: virtualRow ? `${parentRowRef.current?.getBoundingClientRect()?.height}px` : undefined,
? `${parentRowRef.current?.getBoundingClientRect()?.height}px` transform: virtualRow ? `translateY(${virtualRow?.start}px)` : undefined,
: undefined, width: "100%",
transform: virtualRow ...parseFromValuesOrFunc(tableRowProps?.sx, theme),
? `translateY(${virtualRow?.start}px)`
: undefined,
width: '100%',
...(parseFromValuesOrFunc(tableRowProps?.sx, theme)),
})} })}
> >
<TableCell <TableCell
@@ -70,12 +65,12 @@ const DataTable_TableDetailPanel = ({
{...tableCellProps} {...tableCellProps}
sx={(theme) => ({ sx={(theme) => ({
backgroundColor: virtualRow ? baseBackgroundColor : undefined, backgroundColor: virtualRow ? baseBackgroundColor : undefined,
borderBottom: !row.getIsExpanded() ? 'none' : undefined, borderBottom: !row.getIsExpanded() ? "none" : undefined,
display: layoutMode?.startsWith('grid') ? 'flex' : undefined, display: layoutMode?.startsWith("grid") ? "flex" : undefined,
py: !!DetailPanel && row.getIsExpanded() ? '1rem' : 0, py: !!DetailPanel && row.getIsExpanded() ? "1rem" : 0,
transition: !virtualRow ? 'all 150ms ease-in-out' : undefined, transition: !virtualRow ? "all 150ms ease-in-out" : undefined,
width: `100%`, width: `100%`,
...(parseFromValuesOrFunc(tableCellProps?.sx, theme)), ...parseFromValuesOrFunc(tableCellProps?.sx, theme),
})} })}
> >
{virtualRow ? ( {virtualRow ? (
@@ -88,6 +83,5 @@ const DataTable_TableDetailPanel = ({
</TableCell> </TableCell>
</TableRow> </TableRow>
); );
};
} export default DataTable_TableDetailPanel;
export default DataTable_TableDetailPanel

View File

@@ -2,11 +2,7 @@ import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils
import { Button, Tooltip } from "@mui/material"; import { Button, Tooltip } from "@mui/material";
import { useState } from "react"; import { useState } from "react";
const DataTable_CopyButton = ({ const DataTable_CopyButton = ({ cell, table, ...rest }) => {
cell,
table,
...rest
}) => {
const { const {
options: { localization, muiCopyButtonProps }, options: { localization, muiCopyButtonProps },
} = table; } = table;
@@ -40,11 +36,8 @@ const DataTable_CopyButton = ({
return ( return (
<Tooltip <Tooltip
{...getCommonTooltipProps('top')} {...getCommonTooltipProps("top")}
title={ title={buttonProps?.title ?? (copied ? localization.copiedToClipboard : localization.clickToCopy)}
buttonProps?.title ??
(copied ? localization.copiedToClipboard : localization.clickToCopy)
}
> >
<Button <Button
onClick={(e) => handleCopy(e, cell.getValue())} onClick={(e) => handleCopy(e, cell.getValue())}
@@ -53,23 +46,23 @@ const DataTable_CopyButton = ({
variant="text" variant="text"
{...buttonProps} {...buttonProps}
sx={(theme) => ({ sx={(theme) => ({
backgroundColor: 'transparent', backgroundColor: "transparent",
border: 'none', border: "none",
color: 'inherit', color: "inherit",
cursor: 'copy', cursor: "copy",
fontFamily: 'inherit', fontFamily: "inherit",
fontSize: 'inherit', fontSize: "inherit",
letterSpacing: 'inherit', letterSpacing: "inherit",
m: '-0.25rem', m: "-0.25rem",
minWidth: 'unset', minWidth: "unset",
py: 0, py: 0,
textAlign: 'inherit', textAlign: "inherit",
textTransform: 'inherit', textTransform: "inherit",
...(parseFromValuesOrFunc(buttonProps?.sx, theme)), ...parseFromValuesOrFunc(buttonProps?.sx, theme),
})} })}
title={undefined} title={undefined}
/> />
</Tooltip> </Tooltip>
); );
} };
export default DataTable_CopyButton export default DataTable_CopyButton;

View File

@@ -1,11 +1,7 @@
import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils"; import { getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils";
import { IconButton, Tooltip } from "@mui/material"; import { IconButton, Tooltip } from "@mui/material";
const DataTable_GrabHandleButton = ({ const DataTable_GrabHandleButton = ({ location, table, ...rest }) => {
location,
table,
...rest
}) => {
const { const {
options: { options: {
icons: { DragHandleIcon }, icons: { DragHandleIcon },
@@ -14,10 +10,7 @@ const DataTable_GrabHandleButton = ({
} = table; } = table;
return ( return (
<Tooltip <Tooltip {...getCommonTooltipProps("top")} title={rest?.title ?? localization.move}>
{...getCommonTooltipProps('top')}
title={rest?.title ?? localization.move}
>
<IconButton <IconButton
aria-label={rest.title ?? localization.move} aria-label={rest.title ?? localization.move}
disableRipple disableRipple
@@ -29,19 +22,19 @@ const DataTable_GrabHandleButton = ({
rest?.onClick?.(e); rest?.onClick?.(e);
}} }}
sx={(theme) => ({ sx={(theme) => ({
'&:active': { "&:active": {
cursor: 'grabbing', cursor: "grabbing",
}, },
'&:hover': { "&:hover": {
backgroundColor: 'transparent', backgroundColor: "transparent",
opacity: 1, opacity: 1,
}, },
cursor: 'grab', cursor: "grab",
m: '0 -0.1rem', m: "0 -0.1rem",
opacity: location === 'row' ? 1 : 0.5, opacity: location === "row" ? 1 : 0.5,
p: '2px', p: "2px",
transition: 'all 150ms ease-in-out', transition: "all 150ms ease-in-out",
...(parseFromValuesOrFunc(rest?.sx, theme)), ...parseFromValuesOrFunc(rest?.sx, theme),
})} })}
title={undefined} title={undefined}
> >
@@ -49,6 +42,5 @@ const DataTable_GrabHandleButton = ({
</IconButton> </IconButton>
</Tooltip> </Tooltip>
); );
};
} export default DataTable_GrabHandleButton;
export default DataTable_GrabHandleButton

View File

@@ -19,23 +19,12 @@ const DataTable_ShowHideColumnsButton = ({ table, ...rest }) => {
return ( return (
<> <>
<Tooltip title={rest?.title ?? localization.showHideColumns}> <Tooltip title={rest?.title ?? localization.showHideColumns}>
<IconButton <IconButton aria-label={localization.showHideColumns} onClick={handleClick} {...rest} title={undefined}>
aria-label={localization.showHideColumns}
onClick={handleClick}
{...rest}
title={undefined}
>
<ViewColumnIcon /> <ViewColumnIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
{anchorEl && ( {anchorEl && <DataTable_ShowHideColumnsMenu anchorEl={anchorEl} setAnchorEl={setAnchorEl} table={table} />}
<DataTable_ShowHideColumnsMenu
anchorEl={anchorEl}
setAnchorEl={setAnchorEl}
table={table}
/>
)}
</> </>
); );
} };
export default DataTable_ShowHideColumnsButton export default DataTable_ShowHideColumnsButton;

View File

@@ -1,4 +1,4 @@
const DataTable_ToggleFiltersButton = ({ table, ...rest }) => { const DataTable_ToggleFiltersButton = ({ table, ...rest }) => {
return <></> return <></>;
} };
export default DataTable_ToggleFiltersButton export default DataTable_ToggleFiltersButton;

View File

@@ -1,38 +1,38 @@
'use client' "use client";
import {Box, Button, Drawer, styled} from "@mui/material"; import { Box, Button, Drawer, styled } from "@mui/material";
import {Form, Formik} from "formik"; import { Form, Formik } from "formik";
import useTableSetting from "@/lib/hooks/useTableSetting"; import useTableSetting from "@/lib/hooks/useTableSetting";
import {useEffect, useRef, useState} from "react"; import { useEffect, useRef, useState } from "react";
import FilterHeader from "@/core/components/DataTable/filter/FilterHeader"; import FilterHeader from "@/core/components/DataTable/filter/FilterHeader";
import * as Yup from "yup"; import * as Yup from "yup";
import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField"; import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField";
import {toast} from "react-toastify"; import { toast } from "react-toastify";
import AskForKeep from "@/core/components/NotificationDesign/AskForKeep"; import AskForKeep from "@/core/components/NotificationDesign/AskForKeep";
import useDataTable from "@/lib/hooks/useDataTable"; import useDataTable from "@/lib/hooks/useDataTable";
const ScrollBox = styled(Box)({ const ScrollBox = styled(Box)({
flexGrow: 1, flexGrow: 1,
overflowY: 'scroll', overflowY: "scroll",
maxWidth: "450px", maxWidth: "450px",
'::-webkit-scrollbar': { "::-webkit-scrollbar": {
width: '5px', width: "5px",
}, },
'::-webkit-scrollbar-track': { "::-webkit-scrollbar-track": {
boxShadow: 'inset 0 0 5px #fff', boxShadow: "inset 0 0 5px #fff",
borderRadius: '5px', borderRadius: "5px",
},
"::-webkit-scrollbar-thumb": {
background: "#155175",
borderRadius: "0px",
}, },
'::-webkit-scrollbar-thumb': {
background: '#155175',
borderRadius: '0px',
}
}); });
function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, table_name}) { function FilterBody({ columns, drawerState, setDrawerState, user_id, page_name, table_name }) {
const {settingStore, filterAction} = useTableSetting(); const { settingStore, filterAction } = useTableSetting();
const [initialValues, setInitialValues] = useState({}); const [initialValues, setInitialValues] = useState({});
const [validationSchema, setValidationSchema] = useState({}); const [validationSchema, setValidationSchema] = useState({});
const {filterData, setFilterData} = useDataTable(); const { filterData, setFilterData } = useDataTable();
const filterDataRef = useRef(filterData); const filterDataRef = useRef(filterData);
useEffect(() => { useEffect(() => {
filterDataRef.current = filterData; filterDataRef.current = filterData;
@@ -41,27 +41,29 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
useEffect(() => { useEffect(() => {
const values = columns.reduce((acc, column) => { const values = columns.reduce((acc, column) => {
if (!column.enableColumnFilter) return acc; if (!column.enableColumnFilter) return acc;
const filter = settingStore?.[user_id]?.[page_name]?.[table_name]?.['filters']?.find((filter) => filter.id === column.id); const filter = settingStore?.[user_id]?.[page_name]?.[table_name]?.["filters"]?.find(
if (column.datatype === 'array') { (filter) => filter.id === column.id
);
if (column.datatype === "array") {
acc[column.id] = { acc[column.id] = {
id: column.id, id: column.id,
value: filter?.value || [], value: filter?.value || [],
filterFn: filter?.fn || column._filterFn, filterFn: filter?.fn || column._filterFn,
datatype: column.datatype datatype: column.datatype,
}; };
} else if (column._filterFn === "between") { } else if (column._filterFn === "between") {
acc[column.id] = { acc[column.id] = {
id: column.id, id: column.id,
value: filter?.value || ["", ""], value: filter?.value || ["", ""],
filterFn: filter?.fn || column._filterFn, filterFn: filter?.fn || column._filterFn,
datatype: column.datatype datatype: column.datatype,
}; };
} else { } else {
acc[column.id] = { acc[column.id] = {
id: column.id, id: column.id,
value: filter?.value || '', value: filter?.value || "",
filterFn: filter?.fn || column._filterFn, filterFn: filter?.fn || column._filterFn,
datatype: column.datatype datatype: column.datatype,
}; };
} }
return acc; return acc;
@@ -69,7 +71,6 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values); setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values);
}, [columns, settingStore, user_id, page_name, table_name, filterData]); }, [columns, settingStore, user_id, page_name, table_name, filterData]);
useEffect(() => { useEffect(() => {
const generatedSchema = Yup.object().shape( const generatedSchema = Yup.object().shape(
Object.keys(initialValues).reduce((acc, key) => { Object.keys(initialValues).reduce((acc, key) => {
@@ -81,7 +82,10 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
.test({ .test({
test(value, ctx) { test(value, ctx) {
const [start, end] = value || ["", ""]; const [start, end] = value || ["", ""];
if (initialValue.datatype === "numeric" && parseInt(end, 10) <= parseInt(start, 10)) { if (
initialValue.datatype === "numeric" &&
parseInt(end, 10) <= parseInt(start, 10)
) {
return ctx.createError({ return ctx.createError({
message: `مقدار وارده باید بیشتر از (${start}) باشد`, message: `مقدار وارده باید بیشتر از (${start}) باشد`,
}); });
@@ -102,12 +106,11 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
setValidationSchema(generatedSchema); setValidationSchema(generatedSchema);
}, [initialValues]); }, [initialValues]);
const handleSubmit = (values, { setSubmitting }) => {
const handleSubmit = (values, {setSubmitting}) => { toast.dismiss({ containerId: "filtering" });
toast.dismiss({containerId: "filtering"});
setDrawerState(false); setDrawerState(false);
setFilterData(values); setFilterData(values);
toast(<AskForKeep onSaveFilter={onSaveFilter}/>, { toast(<AskForKeep onSaveFilter={onSaveFilter} />, {
containerId: "filtering", containerId: "filtering",
className: "filter-toast", className: "filter-toast",
position: "bottom-left", position: "bottom-left",
@@ -119,84 +122,98 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
const onSaveFilter = () => { const onSaveFilter = () => {
const currentFilterData = filterDataRef.current; const currentFilterData = filterDataRef.current;
const arrayOfObjects = Object.keys(currentFilterData).map(key => { const arrayOfObjects = Object.keys(currentFilterData)
const value = currentFilterData[key].value; .map((key) => {
if (value !== "" && const value = currentFilterData[key].value;
!(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) { if (
return currentFilterData[key]; value !== "" &&
} !(
}).filter(Boolean); Array.isArray(value) &&
filterAction(user_id, page_name, table_name, arrayOfObjects, columns) (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === ""))
toast.dismiss({containerId: "filtering"}); )
) {
return currentFilterData[key];
}
})
.filter(Boolean);
filterAction(user_id, page_name, table_name, arrayOfObjects, columns);
toast.dismiss({ containerId: "filtering" });
}; };
return ( return (
<Drawer open={drawerState} onClose={() => setDrawerState(false)} <Drawer
sx={{overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%"}}> open={drawerState}
<FilterHeader setDrawerState={setDrawerState}/> onClose={() => setDrawerState(false)}
sx={{
overflowY: "hidden",
display: "flex",
flexDirection: "column",
height: "100%",
}}
>
<FilterHeader setDrawerState={setDrawerState} />
{Object.keys(initialValues).length > 0 && ( {Object.keys(initialValues).length > 0 && (
<ScrollBox> <ScrollBox>
<Formik <Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={validationSchema}>
initialValues={initialValues} {({
onSubmit={handleSubmit} values,
validationSchema={validationSchema} handleChange,
> handleBlur,
{ setFieldValue,
({ errors,
values, touched,
handleChange, isSubmitting,
handleBlur, isValid,
setFieldValue, dirty,
errors, resetForm,
touched, }) => (
isSubmitting, <Form>
isValid, <Box sx={{ px: 1, py: 2 }}>
dirty, {columns.map(
resetForm (column) =>
}) => ( column.enableColumnFilter && (
<Form> <FilterBodyField
<Box sx={{px: 1, py: 2}}> key={column.id}
{ column={column}
columns.map((column) => ( filterParameters={values[column.id]}
column.enableColumnFilter && ( handleChange={handleChange}
<FilterBodyField handleBlur={handleBlur}
key={column.id} setFieldValue={setFieldValue}
column={column} resetForm={resetForm}
filterParameters={values[column.id]} errors={errors}
handleChange={handleChange} touched={touched}
handleBlur={handleBlur} />
setFieldValue={setFieldValue} )
resetForm={resetForm} )}
errors={errors} </Box>
touched={touched} <Box
/> sx={{
) display: "flex",
)) justifyContent: "center",
} alignItems: "center",
</Box> pb: 2,
<Box sx={{ }}
display: 'flex', >
justifyContent: 'center', <Button
alignItems: 'center', type="submit"
pb: 2 variant="contained"
}}> size="large"
<Button disabled={isSubmitting || !isValid || !dirty}
type="submit" sx={{
variant="contained" px: 8,
size="large" boxShadow:
disabled={isSubmitting || !isValid || !dirty} "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
sx={{ backgroundColor: "#155175",
px: 8, ":hover": {
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px", backgroundColor: "#155175",
backgroundColor: "#155175", ':hover': { },
backgroundColor: "#155175", }}
} >
}}> اعمال فیلتر
اعمال فیلتر </Button>
</Button> </Box>
</Box> </Form>
</Form> )}
)}
</Formik> </Formik>
</ScrollBox> </ScrollBox>
)} )}
@@ -204,4 +221,4 @@ function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, t
); );
} }
export default FilterBody; export default FilterBody;

View File

@@ -1,4 +1,4 @@
import {useState} from "react"; import { useState } from "react";
import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList"; import FilterOptionList from "@/core/components/DataTable/filter/FilterOptionList";
import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect"; import CustomSelect from "@/core/components/DataTable/filter/fieldsType/CustomSelect";
import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField"; import CustomTextField from "@/core/components/DataTable/filter/fieldsType/CustomTextField";
@@ -14,19 +14,19 @@ const columnFilterModeOptionFa = {
lessThan: "کوچکتر", lessThan: "کوچکتر",
greaterThan: "بزرگتر", greaterThan: "بزرگتر",
fuzzy: "فازی", fuzzy: "فازی",
between: "مابین" between: "مابین",
}; };
function FilterBodyField({ function FilterBodyField({
column, column,
filterParameters, filterParameters,
handleChange, handleChange,
handleBlur, handleBlur,
setFieldValue, setFieldValue,
errors, errors,
touched, touched,
resetForm resetForm,
}) { }) {
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const defaultFilterTranslation = columnFilterModeOptionFa[filterParameters.filterFn] || filterParameters.filterFn; const defaultFilterTranslation = columnFilterModeOptionFa[filterParameters.filterFn] || filterParameters.filterFn;
@@ -47,7 +47,9 @@ function FilterBodyField({
errors={errors} errors={errors}
touched={touched} touched={touched}
/> />
) : filterParameters.datatype === "numeric" && filterParameters.filterFn === "equals" && Array.isArray(column.columnSelectOption) ? ( ) : filterParameters.datatype === "numeric" &&
filterParameters.filterFn === "equals" &&
Array.isArray(column.columnSelectOption) ? (
<CustomSelect <CustomSelect
column={column} column={column}
filterParameters={filterParameters} filterParameters={filterParameters}
@@ -108,4 +110,4 @@ function FilterBodyField({
); );
} }
export default FilterBodyField; export default FilterBodyField;

View File

@@ -1,14 +1,17 @@
'use client' "use client";
import FilterAltIcon from '@mui/icons-material/FilterAlt'; import FilterAltIcon from "@mui/icons-material/FilterAlt";
import {IconButton, Tooltip} from "@mui/material"; import { IconButton, Tooltip } from "@mui/material";
function FilterButton({drawerState, setDrawerState}) { function FilterButton({ drawerState, setDrawerState }) {
return ( return (
<Tooltip title="فیلتر"> <Tooltip title="فیلتر">
<IconButton onClick={() => { <IconButton
setDrawerState(!drawerState) onClick={() => {
}} aria-label="filter table"> setDrawerState(!drawerState);
<FilterAltIcon/> }}
aria-label="filter table"
>
<FilterAltIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
); );

View File

@@ -1,10 +1,10 @@
'use client' "use client";
import {Box, IconButton, Typography} from "@mui/material"; import { Box, IconButton, Typography } from "@mui/material";
import CancelIcon from '@mui/icons-material/Cancel'; import CancelIcon from "@mui/icons-material/Cancel";
import FilterAltIcon from '@mui/icons-material/FilterAlt'; import FilterAltIcon from "@mui/icons-material/FilterAlt";
function FilterHeader({setDrawerState}) { function FilterHeader({ setDrawerState }) {
return ( return (
<Box <Box
sx={{ sx={{
@@ -15,18 +15,20 @@ function FilterHeader({setDrawerState}) {
py: 1, py: 1,
backgroundColor: "#155175", backgroundColor: "#155175",
boxShadow: "rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px", boxShadow: "rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px",
maxWidth: "450px" maxWidth: "450px",
}} }}
> >
<Box sx={{display: "flex", alignItems: "center"}}> <Box sx={{ display: "flex", alignItems: "center" }}>
<FilterAltIcon sx={{color: "#fff"}}/> <FilterAltIcon sx={{ color: "#fff" }} />
<Typography variant="h6" sx={{color: "#fff"}}>فیلتر</Typography> <Typography variant="h6" sx={{ color: "#fff" }}>
فیلتر
</Typography>
</Box> </Box>
<IconButton sx={{color: "#fff"}} onClick={() => setDrawerState(false)}> <IconButton sx={{ color: "#fff" }} onClick={() => setDrawerState(false)}>
<CancelIcon sx={{fontSize: "1em"}}/> <CancelIcon sx={{ fontSize: "1em" }} />
</IconButton> </IconButton>
</Box> </Box>
); );
} }
export default FilterHeader; export default FilterHeader;

View File

@@ -1,17 +1,17 @@
'use client' "use client";
import {ListItem, Menu} from "@mui/material"; import { ListItem, Menu } from "@mui/material";
import {useState} from "react"; import { useState } from "react";
function FilterOptionList({ function FilterOptionList({
column, column,
filterType, filterType,
filterOption, filterOption,
anchorEl, anchorEl,
columnFilterModeOptionFa, columnFilterModeOptionFa,
setAnchorEl, setAnchorEl,
setFieldValue setFieldValue,
}) { }) {
const [selectedFilter, setSelectedFilter] = useState(filterType); const [selectedFilter, setSelectedFilter] = useState(filterType);
const handleChangeItem = (event, index) => { const handleChangeItem = (event, index) => {
@@ -19,25 +19,26 @@ function FilterOptionList({
setFieldValue(`${column.id}.filterFn`, filterOption[index]); setFieldValue(`${column.id}.filterFn`, filterOption[index]);
setSelectedFilter(filterOption[index]); setSelectedFilter(filterOption[index]);
setAnchorEl(null); setAnchorEl(null);
} };
const handleCloseFilterBox = () => { const handleCloseFilterBox = () => {
setAnchorEl(null); setAnchorEl(null);
}; };
return ( return (
<Menu <Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleCloseFilterBox}>
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleCloseFilterBox}
>
{filterOption.map((option, index) => ( {filterOption.map((option, index) => (
<ListItem key={index} <ListItem
onClick={(event) => handleChangeItem(event, index)} key={index}
selected={option === selectedFilter} onClick={(event) => handleChangeItem(event, index)}
sx={{cursor: 'pointer', width: "100px", display: "flex", justifyContent: "center"}}> selected={option === selectedFilter}
sx={{
cursor: "pointer",
width: "100px",
display: "flex",
justifyContent: "center",
}}
>
{columnFilterModeOptionFa[option]} {columnFilterModeOptionFa[option]}
</ListItem> </ListItem>
))} ))}
@@ -45,4 +46,4 @@ function FilterOptionList({
); );
} }
export default FilterOptionList; export default FilterOptionList;

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React from "react";
import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker"; import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker";
import {Typography} from "@mui/material"; import { Typography } from "@mui/material";
function CustomDatePicker({column, filterParameters, defaultFilterTranslation, setFieldValue}) { function CustomDatePicker({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
return ( return (
<MuiDatePicker <MuiDatePicker
name={`${column.id}.value`} name={`${column.id}.value`}
@@ -10,7 +10,7 @@ function CustomDatePicker({column, filterParameters, defaultFilterTranslation, s
setFieldValue={setFieldValue} setFieldValue={setFieldValue}
placeholder={column.header} placeholder={column.header}
helperText={ helperText={
<Typography variant="button" sx={{color: "#155175"}}> <Typography variant="button" sx={{ color: "#155175" }}>
نوع فیلتر: {defaultFilterTranslation} (تاریخ) نوع فیلتر: {defaultFilterTranslation} (تاریخ)
</Typography> </Typography>
} }
@@ -18,4 +18,4 @@ function CustomDatePicker({column, filterParameters, defaultFilterTranslation, s
); );
} }
export default CustomDatePicker; export default CustomDatePicker;

View File

@@ -1,12 +1,12 @@
'use client' "use client";
import React from "react"; import React from "react";
import {Box, Typography} from "@mui/material"; import { Box, Typography } from "@mui/material";
import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker"; import MuiDatePicker from "@/core/components/DataTable/filter/fieldsType/CustomDate/MuiDatePicker";
function CustomDatePickerRange({column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched}) { function CustomDatePickerRange({ column, filterParameters, defaultFilterTranslation, setFieldValue, errors, touched }) {
return ( return (
<Box sx={{display: "flex", gap: 1}}> <Box sx={{ display: "flex", gap: 1 }}>
<MuiDatePicker <MuiDatePicker
name={`${column.id}.value[0]`} name={`${column.id}.value[0]`}
value={filterParameters.value[0]} value={filterParameters.value[0]}
@@ -14,7 +14,7 @@ function CustomDatePickerRange({column, filterParameters, defaultFilterTranslati
maxDate={filterParameters.value[1]} maxDate={filterParameters.value[1]}
placeholder={`از تاریخ`} placeholder={`از تاریخ`}
helperText={ helperText={
<Typography variant="button" sx={{color: "#155175"}}> <Typography variant="button" sx={{ color: "#155175" }}>
نوع فیلتر: {defaultFilterTranslation} (تاریخ) نوع فیلتر: {defaultFilterTranslation} (تاریخ)
</Typography> </Typography>
} }

View File

@@ -1,33 +1,31 @@
import React from 'react'; import React from "react";
import {LocalizationProvider, MobileDatePicker} from "@mui/x-date-pickers"; import { LocalizationProvider, MobileDatePicker } from "@mui/x-date-pickers";
import {AdapterDateFnsJalali} from "@mui/x-date-pickers/AdapterDateFnsJalali"; import { AdapterDateFnsJalali } from "@mui/x-date-pickers/AdapterDateFnsJalali";
import {faIR} from "@mui/x-date-pickers/locales"; import { faIR } from "@mui/x-date-pickers/locales";
import {Box, FormHelperText, IconButton, InputAdornment} from "@mui/material"; import { Box, FormHelperText, IconButton, InputAdornment } from "@mui/material";
import ClearIcon from "@mui/icons-material/Clear"; import ClearIcon from "@mui/icons-material/Clear";
import moment from "jalali-moment"; import moment from "jalali-moment";
function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error}) { function MuiDatePicker({ value, setFieldValue, name, minDate, maxDate, helperText, placeholder, error }) {
// console.log("error", error); // console.log("error", error);
// //
// console.log("helperText", helperText) // console.log("helperText", helperText)
return ( return (
<Box sx={{display: "flex", flexDirection: "column", my: 1}}> <Box sx={{ display: "flex", flexDirection: "column", my: 1 }}>
<LocalizationProvider dateAdapter={AdapterDateFnsJalali} <LocalizationProvider
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText} dateAdapter={AdapterDateFnsJalali}
localeText={faIR.components.MuiLocalizationProvider.defaultProps.localeText}
> >
<MobileDatePicker <MobileDatePicker
value={value ? new Date(value) : null} value={value ? new Date(value) : null}
sx={{width: "100%"}} sx={{ width: "100%" }}
id={name} id={name}
name={name} name={name}
aria-describedby="component-helper-text" aria-describedby="component-helper-text"
onChange={(value) => { onChange={(value) => {
const date = new Date(value); const date = new Date(value);
const formattedDate = moment(date) const formattedDate = moment(date).locale("en").format("YYYY-MM-DD");
.locale("en")
.format("YYYY-MM-DD");
setFieldValue(name, formattedDate); setFieldValue(name, formattedDate);
}} }}
minDate={minDate ? new Date(minDate) : null} minDate={minDate ? new Date(minDate) : null}
@@ -47,13 +45,13 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
}} }}
sx={{ sx={{
color: "#bfbfbf", color: "#bfbfbf",
'&:hover': { "&:hover": {
backgroundColor: 'rgba(189, 189, 189, 0.1)', backgroundColor: "rgba(189, 189, 189, 0.1)",
color: "#363434" color: "#363434",
}, },
}} }}
> >
<ClearIcon/> <ClearIcon />
</IconButton> </IconButton>
</InputAdornment> </InputAdornment>
), ),
@@ -61,7 +59,7 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
}, },
}} }}
/> />
<FormHelperText id="component-helper-text" sx={{ml: 2, color: error ? '#d32f2f' : "unset"}}> <FormHelperText id="component-helper-text" sx={{ ml: 2, color: error ? "#d32f2f" : "unset" }}>
{helperText ? helperText : ""} {helperText ? helperText : ""}
</FormHelperText> </FormHelperText>
</LocalizationProvider> </LocalizationProvider>
@@ -69,4 +67,4 @@ function MuiDatePicker({value, setFieldValue, name, minDate, maxDate, helperText
); );
} }
export default MuiDatePicker; export default MuiDatePicker;

View File

@@ -1,35 +1,32 @@
'use client' "use client";
import {FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography} from "@mui/material"; import { FormControl, FormHelperText, InputLabel, MenuItem, OutlinedInput, Select, Typography } from "@mui/material";
function CustomSelect({column, filterParameters, defaultFilterTranslation, setFieldValue}) { function CustomSelect({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
const columnSelectOption = column.columnSelectOption; const columnSelectOption = column.columnSelectOption;
return ( return (
<FormControl fullWidth sx={{marginY: 1}}> <FormControl fullWidth sx={{ marginY: 1 }}>
<InputLabel id={`label${column.id}`}>{column.header}</InputLabel> <InputLabel id={`label${column.id}`}>{column.header}</InputLabel>
<Select <Select
labelId={`label${column.id}`} labelId={`label${column.id}`}
id={column.id} id={column.id}
name={`${column.id}.value`} name={`${column.id}.value`}
value={filterParameters.value} value={filterParameters.value}
input={<OutlinedInput label={column.header}/>} input={<OutlinedInput label={column.header} />}
onChange={(e) => { onChange={(e) => {
setFieldValue(`${column.id}.value`, e.target.value) setFieldValue(`${column.id}.value`, e.target.value);
}} }}
> >
<MenuItem value="">{column.header}</MenuItem> <MenuItem value="">{column.header}</MenuItem>
{columnSelectOption.map((option) => ( {columnSelectOption.map((option) => (
<MenuItem <MenuItem key={option.value} value={option.value}>
key={option.value}
value={option.value}
>
{option.label} {option.label}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
<FormHelperText> <FormHelperText>
<Typography variant="button" sx={{color: "#155175"}}> <Typography variant="button" sx={{ color: "#155175" }}>
نوع فیلتر: {defaultFilterTranslation} نوع فیلتر: {defaultFilterTranslation}
</Typography> </Typography>
</FormHelperText> </FormHelperText>

View File

@@ -1,4 +1,4 @@
'use client' "use client";
import { import {
Box, Box,
@@ -9,49 +9,47 @@ import {
MenuItem, MenuItem,
OutlinedInput, OutlinedInput,
Select, Select,
Typography Typography,
} from "@mui/material"; } from "@mui/material";
function CustomSelectMultiple({column, filterParameters, defaultFilterTranslation, setFieldValue}) { function CustomSelectMultiple({ column, filterParameters, defaultFilterTranslation, setFieldValue }) {
const columnSelectOption = column.columnSelectOption; const columnSelectOption = column.columnSelectOption;
const getLabelForValue = (value) => { const getLabelForValue = (value) => {
const option = columnSelectOption.find(opt => opt.value === value); const option = columnSelectOption.find((opt) => opt.value === value);
return option ? option.label : value; return option ? option.label : value;
}; };
return ( return (
<FormControl fullWidth sx={{marginY: 1}}> <FormControl fullWidth sx={{ marginY: 1 }}>
<InputLabel htmlFor="uncontrolled-native" <InputLabel htmlFor="uncontrolled-native" id={`label${column.id}`}>
id={`label${column.id}`}>{column.header}</InputLabel> {column.header}
</InputLabel>
<Select <Select
labelId={`label${column.id}`} labelId={`label${column.id}`}
id={column.id} id={column.id}
value={filterParameters.value} value={filterParameters.value}
multiple multiple
onChange={(e) => { onChange={(e) => {
setFieldValue(`${column.id}.value`, e.target.value) setFieldValue(`${column.id}.value`, e.target.value);
}} }}
renderValue={(selected) => ( renderValue={(selected) => (
<Box sx={{display: 'flex', flexWrap: 'wrap', gap: 0.5}}> <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
{selected.map((value) => ( {selected.map((value) => (
<Chip key={value} label={getLabelForValue(value)}/> <Chip key={value} label={getLabelForValue(value)} />
))} ))}
</Box> </Box>
)} )}
input={<OutlinedInput label={column.header}/>} input={<OutlinedInput label={column.header} />}
> >
{columnSelectOption.map((option) => ( {columnSelectOption.map((option) => (
<MenuItem <MenuItem key={option.value} value={option.value}>
key={option.value}
value={option.value}
>
{option.label} {option.label}
</MenuItem> </MenuItem>
))} ))}
</Select> </Select>
<FormHelperText> <FormHelperText>
<Typography variant="button" sx={{color: "#155175"}}> <Typography variant="button" sx={{ color: "#155175" }}>
نوع فیلتر: {defaultFilterTranslation} نوع فیلتر: {defaultFilterTranslation}
</Typography> </Typography>
</FormHelperText> </FormHelperText>

View File

@@ -1,15 +1,14 @@
import {InputAdornment, TextField, Typography} from "@mui/material"; import { InputAdornment, TextField, Typography } from "@mui/material";
import FilterListIcon from '@mui/icons-material/FilterList'; import FilterListIcon from "@mui/icons-material/FilterList";
function CustomTextField({ function CustomTextField({
column, column,
filterParameters, filterParameters,
defaultFilterTranslation, defaultFilterTranslation,
handleOpenFilterBox, handleOpenFilterBox,
handleChange, handleChange,
handleBlur handleBlur,
}) { }) {
return ( return (
<TextField <TextField
id={column.id} id={column.id}
@@ -19,16 +18,18 @@ function CustomTextField({
onChange={handleChange} onChange={handleChange}
onBlur={handleBlur} onBlur={handleBlur}
fullWidth fullWidth
helperText={<Typography variant="button" sx={{color: "#155175"}}> helperText={
نوع فیلتر: {defaultFilterTranslation} <Typography variant="button" sx={{ color: "#155175" }}>
</Typography>} نوع فیلتر: {defaultFilterTranslation}
</Typography>
}
variant="outlined" variant="outlined"
size="normal" size="normal"
sx={{marginY: 1}} sx={{ marginY: 1 }}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end" sx={{cursor: "pointer"}} onClick={handleOpenFilterBox}> <InputAdornment position="end" sx={{ cursor: "pointer" }} onClick={handleOpenFilterBox}>
<FilterListIcon/> <FilterListIcon />
</InputAdornment> </InputAdornment>
), ),
}} }}
@@ -36,4 +37,4 @@ function CustomTextField({
); );
} }
export default CustomTextField; export default CustomTextField;

View File

@@ -1,18 +1,18 @@
import {Box, InputAdornment, TextField, Typography} from "@mui/material"; import { Box, InputAdornment, TextField, Typography } from "@mui/material";
import FilterListIcon from '@mui/icons-material/FilterList'; import FilterListIcon from "@mui/icons-material/FilterList";
function CustomTextFieldRange({ function CustomTextFieldRange({
column, column,
filterParameters, filterParameters,
defaultFilterTranslation, defaultFilterTranslation,
handleOpenFilterBox, handleOpenFilterBox,
handleChange, handleChange,
handleBlur, handleBlur,
errors, errors,
touched touched,
}) { }) {
return ( return (
<Box sx={{display: "flex"}}> <Box sx={{ display: "flex" }}>
<TextField <TextField
id={`${column.id}.value[0]`} id={`${column.id}.value[0]`}
name={`${column.id}.value[0]`} name={`${column.id}.value[0]`}
@@ -22,11 +22,14 @@ function CustomTextFieldRange({
value={filterParameters.value[0]} value={filterParameters.value[0]}
fullWidth fullWidth
error={touched?.[`${column.id}`]?.value && Boolean(errors?.[`${column.id}`]?.value)} error={touched?.[`${column.id}`]?.value && Boolean(errors?.[`${column.id}`]?.value)}
helperText={<Typography variant="button" sx={{color: "#155175"}}>نوع helperText={
فیلتر: {defaultFilterTranslation}</Typography>} <Typography variant="button" sx={{ color: "#155175" }}>
نوع فیلتر: {defaultFilterTranslation}
</Typography>
}
variant="outlined" variant="outlined"
size="normal" size="normal"
sx={{marginY: 1, marginRight: 1}} sx={{ marginY: 1, marginRight: 1 }}
/> />
<TextField <TextField
id={`${column.id}.value[1]`} id={`${column.id}.value[1]`}
@@ -40,11 +43,11 @@ function CustomTextFieldRange({
fullWidth fullWidth
variant="outlined" variant="outlined"
size="normal" size="normal"
sx={{marginY: 1}} sx={{ marginY: 1 }}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end" sx={{cursor: "pointer"}} onClick={handleOpenFilterBox}> <InputAdornment position="end" sx={{ cursor: "pointer" }} onClick={handleOpenFilterBox}>
<FilterListIcon/> <FilterListIcon />
</InputAdornment> </InputAdornment>
), ),
}} }}
@@ -53,4 +56,4 @@ function CustomTextFieldRange({
); );
} }
export default CustomTextFieldRange; export default CustomTextFieldRange;

View File

@@ -1,17 +1,23 @@
'use client' "use client";
import {useState} from "react"; import { useState } from "react";
import FilterButton from "@/core/components/DataTable/filter/FilterButton"; import FilterButton from "@/core/components/DataTable/filter/FilterButton";
import FilterBody from "@/core/components/DataTable/filter/FilterBody"; import FilterBody from "@/core/components/DataTable/filter/FilterBody";
function FilterColumn({columns, user_id, page_name, table_name}) { function FilterColumn({ columns, user_id, page_name, table_name }) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
return ( return (
<> <>
<FilterButton drawerState={open} setDrawerState={setOpen}/> <FilterButton drawerState={open} setDrawerState={setOpen} />
<FilterBody columns={columns} drawerState={open} setDrawerState={setOpen} user_id={user_id} <FilterBody
page_name={page_name} table_name={table_name}/> columns={columns}
drawerState={open}
setDrawerState={setOpen}
user_id={user_id}
page_name={page_name}
table_name={table_name}
/>
</> </>
); );
} }

View File

@@ -1,26 +1,17 @@
import {parseFromValuesOrFunc} from "@/core/utils/utils"; import { parseFromValuesOrFunc } from "@/core/utils/utils";
import {TableHead} from "@mui/material"; import { TableHead } from "@mui/material";
import DataTable_TableHeadRow from "./TableHeadRow"; import DataTable_TableHeadRow from "./TableHeadRow";
const DataTable_TableHead = ({ const DataTable_TableHead = ({ columnVirtualizer, table, ...rest }) => {
columnVirtualizer,
table,
...rest
}) => {
const { const {
getState, getState,
options: { options: { enableStickyHeader, layoutMode, muiTableHeadProps, positionToolbarAlertBanner },
enableStickyHeader, refs: { tableHeadRef },
layoutMode,
muiTableHeadProps,
positionToolbarAlertBanner,
},
refs: {tableHeadRef},
} = table; } = table;
const {isFullScreen, showAlertBanner} = getState(); const { isFullScreen, showAlertBanner } = getState();
const tableHeadProps = { const tableHeadProps = {
...parseFromValuesOrFunc(muiTableHeadProps, {table}), ...parseFromValuesOrFunc(muiTableHeadProps, { table }),
...rest, ...rest,
}; };
@@ -37,28 +28,24 @@ const DataTable_TableHead = ({
} }
}} }}
sx={(theme) => ({ sx={(theme) => ({
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
opacity: 0.97, opacity: 0.97,
position: stickyHeader ? 'sticky' : 'relative', position: stickyHeader ? "sticky" : "relative",
top: stickyHeader && layoutMode?.startsWith('grid') ? 0 : undefined, top: stickyHeader && layoutMode?.startsWith("grid") ? 0 : undefined,
zIndex: stickyHeader ? 2 : undefined, zIndex: stickyHeader ? 2 : undefined,
...(parseFromValuesOrFunc(tableHeadProps?.sx, theme)), ...parseFromValuesOrFunc(tableHeadProps?.sx, theme),
})} })}
> >
{table {table.getHeaderGroups().map((headerGroup, index) => (
.getHeaderGroups() <DataTable_TableHeadRow
.map((headerGroup, index) => ( columnVirtualizer={columnVirtualizer}
<DataTable_TableHeadRow headerGroup={headerGroup}
columnVirtualizer={columnVirtualizer} key={headerGroup.id}
headerGroup={headerGroup} table={table}
key={headerGroup.id} index={index}
table={table} />
index={index} ))}
/>
))
}
</TableHead> </TableHead>
); );
};
} export default DataTable_TableHead;
export default DataTable_TableHead

View File

@@ -1,16 +1,10 @@
import {getCommonMRTCellStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; import { getCommonMRTCellStyles, parseFromValuesOrFunc } from "@/core/utils/utils";
import {useTheme} from "@emotion/react"; import { useTheme } from "@emotion/react";
import {Box, TableCell} from "@mui/material"; import { Box, TableCell } from "@mui/material";
import {MRT_TableHeadCellSortLabel} from "material-react-table"; import { MRT_TableHeadCellSortLabel } from "material-react-table";
import {useMemo} from "react"; import { useMemo } from "react";
const DataTable_TableHeadCell = ({ const DataTable_TableHeadCell = ({ columnVirtualizer, header, staticColumnIndex, table, ...rest }) => {
columnVirtualizer,
header,
staticColumnIndex,
table,
...rest
}) => {
const theme = useTheme(); const theme = useTheme();
const { const {
getState, getState,
@@ -24,26 +18,19 @@ const DataTable_TableHeadCell = ({
enableGrouping, enableGrouping,
enableMultiSort, enableMultiSort,
layoutMode, layoutMode,
mrtTheme: {draggingBorderColor}, mrtTheme: { draggingBorderColor },
muiTableHeadCellProps, muiTableHeadCellProps,
}, },
refs: {tableHeadCellRefs}, refs: { tableHeadCellRefs },
setHoveredColumn, setHoveredColumn,
} = table; } = table;
const { const { columnSizingInfo, density, draggingColumn, grouping, hoveredColumn, showColumnFilters } = getState();
columnSizingInfo, const { column } = header;
density, const { columnDef } = column;
draggingColumn, const { columnDefType } = columnDef;
grouping,
hoveredColumn,
showColumnFilters,
} = getState();
const {column} = header;
const {columnDef} = column;
const {columnDefType} = columnDef;
const tableCellProps = { const tableCellProps = {
...parseFromValuesOrFunc(muiTableHeadCellProps, {column, table}), ...parseFromValuesOrFunc(muiTableHeadCellProps, { column, table }),
...parseFromValuesOrFunc(columnDef.muiTableHeadCellProps, { ...parseFromValuesOrFunc(columnDef.muiTableHeadCellProps, {
column, column,
table, table,
@@ -51,23 +38,17 @@ const DataTable_TableHeadCell = ({
...rest, ...rest,
}; };
const isColumnPinned = const isColumnPinned = enableColumnPinning && columnDef.columnDefType !== "group" && column.getIsPinned();
enableColumnPinning &&
columnDef.columnDefType !== 'group' &&
column.getIsPinned();
const showColumnActions = const showColumnActions =
(enableColumnActions || columnDef.enableColumnActions) && (enableColumnActions || columnDef.enableColumnActions) && columnDef.enableColumnActions !== false;
columnDef.enableColumnActions !== false;
const showDragHandle = const showDragHandle =
enableColumnDragging !== false && enableColumnDragging !== false &&
columnDef.enableColumnDragging !== false && columnDef.enableColumnDragging !== false &&
(enableColumnDragging || (enableColumnDragging ||
(enableColumnOrdering && columnDef.enableColumnOrdering !== false) || (enableColumnOrdering && columnDef.enableColumnOrdering !== false) ||
(enableGrouping && (enableGrouping && columnDef.enableGrouping !== false && !grouping.includes(column.id)));
columnDef.enableGrouping !== false &&
!grouping.includes(column.id)));
const headerPL = useMemo(() => { const headerPL = useMemo(() => {
let pl = 0; let pl = 0;
@@ -80,41 +61,37 @@ const DataTable_TableHeadCell = ({
const draggingBorders = useMemo(() => { const draggingBorders = useMemo(() => {
const showResizeBorder = const showResizeBorder =
columnSizingInfo.isResizingColumn === column.id && columnSizingInfo.isResizingColumn === column.id &&
columnResizeMode === 'onChange' && columnResizeMode === "onChange" &&
!header.subHeaders.length; !header.subHeaders.length;
const borderStyle = showResizeBorder const borderStyle = showResizeBorder
? `2px solid ${draggingBorderColor} !important` ? `2px solid ${draggingBorderColor} !important`
: draggingColumn?.id === column.id : draggingColumn?.id === column.id
? `1px dashed ${theme.palette.grey[500]}` ? `1px dashed ${theme.palette.grey[500]}`
: hoveredColumn?.id === column.id : hoveredColumn?.id === column.id
? `2px dashed ${draggingBorderColor}` ? `2px dashed ${draggingBorderColor}`
: undefined; : undefined;
if (showResizeBorder) { if (showResizeBorder) {
return columnResizeDirection === 'ltr' return columnResizeDirection === "ltr" ? { borderRight: borderStyle } : { borderLeft: borderStyle };
? {borderRight: borderStyle}
: {borderLeft: borderStyle};
} }
const draggingBorders = borderStyle const draggingBorders = borderStyle
? { ? {
borderLeft: borderStyle, borderLeft: borderStyle,
borderRight: borderStyle, borderRight: borderStyle,
borderTop: borderStyle, borderTop: borderStyle,
} }
: undefined; : undefined;
return draggingBorders; return draggingBorders;
}, [draggingColumn, hoveredColumn, columnSizingInfo.isResizingColumn]); }, [draggingColumn, hoveredColumn, columnSizingInfo.isResizingColumn]);
const handleDragEnter = (_e) => { const handleDragEnter = (_e) => {
if (enableGrouping && hoveredColumn?.id === 'drop-zone') { if (enableGrouping && hoveredColumn?.id === "drop-zone") {
setHoveredColumn(null); setHoveredColumn(null);
} }
if (enableColumnOrdering && draggingColumn && columnDefType !== 'group') { if (enableColumnOrdering && draggingColumn && columnDefType !== "group") {
setHoveredColumn( setHoveredColumn(columnDef.enableColumnOrdering !== false ? column : null);
columnDef.enableColumnOrdering !== false ? column : null,
);
} }
}; };
@@ -124,7 +101,6 @@ const DataTable_TableHeadCell = ({
} }
}; };
const HeaderElement = const HeaderElement =
parseFromValuesOrFunc(columnDef.Header, { parseFromValuesOrFunc(columnDef.Header, {
column, column,
@@ -132,12 +108,9 @@ const DataTable_TableHeadCell = ({
table, table,
}) ?? columnDef.header; }) ?? columnDef.header;
const columnRelativeDepth = header.depth - column.depth; const columnRelativeDepth = header.depth - column.depth;
if ( if (columnRelativeDepth > 1) {
columnRelativeDepth > 1
) {
return null; return null;
} }
@@ -149,13 +122,7 @@ const DataTable_TableHeadCell = ({
return ( return (
<TableCell <TableCell
align={ align={columnDefType === "group" ? "center" : theme.direction === "rtl" ? "right" : "left"}
columnDefType === 'group'
? 'center'
: theme.direction === 'rtl'
? 'right'
: 'left'
}
colSpan={header.colSpan} colSpan={header.colSpan}
rowSpan={rowSpan} rowSpan={rowSpan}
data-index={staticColumnIndex} data-index={staticColumnIndex}
@@ -165,123 +132,107 @@ const DataTable_TableHeadCell = ({
ref={(node) => { ref={(node) => {
if (node) { if (node) {
tableHeadCellRefs.current[column.id] = node; tableHeadCellRefs.current[column.id] = node;
if (columnDefType !== 'group') { if (columnDefType !== "group") {
columnVirtualizer?.measureElement?.(node); columnVirtualizer?.measureElement?.(node);
} }
} }
}} }}
{...tableCellProps} {...tableCellProps}
sx={(theme) => ({ sx={(theme) => ({
'& :hover': { "& :hover": {
'.MuiButtonBase-root': { ".MuiButtonBase-root": {
opacity: 1, opacity: 1,
},
}, },
flexDirection: layoutMode?.startsWith('grid') ? 'column' : undefined, },
fontWeight: 'bold', flexDirection: layoutMode?.startsWith("grid") ? "column" : undefined,
overflow: 'visible', fontWeight: "bold",
p: overflow: "visible",
density === 'compact' p:
? '0.5rem' density === "compact"
: density === 'comfortable' ? "0.5rem"
? columnDefType === 'display' : density === "comfortable"
? '0.75rem' ? columnDefType === "display"
: '1rem' ? "0.75rem"
: columnDefType === 'display' : "1rem"
? '1rem 1.25rem' : columnDefType === "display"
: '1.5rem', ? "1rem 1.25rem"
pb: : "1.5rem",
columnDefType === 'display' pb: columnDefType === "display" ? 0 : showColumnFilters || density === "compact" ? "0.4rem" : "0.6rem",
? 0 pt:
: showColumnFilters || density === 'compact' columnDefType === "group" || density === "compact"
? '0.4rem' ? "0.25rem"
: '0.6rem', : density === "comfortable"
pt: ? ".75rem"
columnDefType === 'group' || density === 'compact' : "1.25rem",
? '0.25rem' userSelect: enableMultiSort && column.getCanSort() ? "none" : undefined,
: density === 'comfortable' verticalAlign: "middle",
? '.75rem' ...getCommonMRTCellStyles({
: '1.25rem', column,
userSelect: enableMultiSort && column.getCanSort() ? 'none' : undefined, header,
verticalAlign: 'middle', table,
...getCommonMRTCellStyles({ tableCellProps,
column, theme,
header, }),
table, ...draggingBorders,
tableCellProps, })}
theme,
}),
...draggingBorders,
}
)}
> >
{tableCellProps.children ?? ( {tableCellProps.children ?? (
<Box <Box
className="Mui-TableHeadCell-Content" className="Mui-TableHeadCell-Content"
sx={{ sx={{
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
flexDirection: flexDirection: tableCellProps?.align === "right" ? "row-reverse" : "row",
tableCellProps?.align === 'right' ? 'row-reverse' : 'row',
justifyContent: justifyContent:
columnDefType === 'group' || columnDefType === "group" || tableCellProps?.align === "center"
tableCellProps?.align === 'center' ? "center"
? 'center'
: column.getCanResize() : column.getCanResize()
? 'space-between' ? "space-between"
: 'flex-start', : "flex-start",
position: 'relative', position: "relative",
width: '100%', width: "100%",
}} }}
> >
<Box <Box
className="Mui-TableHeadCell-Content-Labels" className="Mui-TableHeadCell-Content-Labels"
onClick={column.getToggleSortingHandler()} onClick={column.getToggleSortingHandler()}
sx={{ sx={{
alignItems: 'center', alignItems: "center",
cursor: cursor: column.getCanSort() && columnDefType !== "group" ? "pointer" : undefined,
column.getCanSort() && columnDefType !== 'group' display: "flex",
? 'pointer' flexDirection: tableCellProps?.align === "right" ? "row-reverse" : "row",
: undefined, overflow: columnDefType === "data" ? "hidden" : undefined,
display: 'flex', pl: tableCellProps?.align === "center" ? `${headerPL}rem` : undefined,
flexDirection:
tableCellProps?.align === 'right' ? 'row-reverse' : 'row',
overflow: columnDefType === 'data' ? 'hidden' : undefined,
pl:
tableCellProps?.align === 'center'
? `${headerPL}rem`
: undefined,
}} }}
> >
<Box <Box
className="Mui-TableHeadCell-Content-Wrapper" className="Mui-TableHeadCell-Content-Wrapper"
sx={{ sx={{
'&:hover': { "&:hover": {
textOverflow: 'clip', textOverflow: "clip",
}, },
minWidth: `${Math.min(columnDef.header?.length ?? 0, 4)}ch`, minWidth: `${Math.min(columnDef.header?.length ?? 0, 4)}ch`,
overflow: columnDefType === 'data' ? 'hidden' : undefined, overflow: columnDefType === "data" ? "hidden" : undefined,
textOverflow: 'ellipsis', textOverflow: "ellipsis",
color: "#fff", color: "#fff",
fontSize: "14px", fontSize: "14px",
fontWeight: "500", fontWeight: "500",
whiteSpace: whiteSpace: (columnDef.header?.length ?? 0) < 20 ? "nowrap" : "normal",
(columnDef.header?.length ?? 0) < 20
? 'nowrap'
: 'normal',
}} }}
> >
{HeaderElement} {HeaderElement}
</Box> </Box>
{(column.getCanSort() && columnDefType !== 'group') && ( {column.getCanSort() && columnDefType !== "group" && (
<MRT_TableHeadCellSortLabel sx={{width: 20, color: "#fff"}} header={header} <MRT_TableHeadCellSortLabel
table={table}/> sx={{ width: 20, color: "#fff" }}
header={header}
table={table}
/>
)} )}
</Box> </Box>
</Box> </Box>
)} )}
</TableCell> </TableCell>
); );
};
} export default DataTable_TableHeadCell;
export default DataTable_TableHeadCell;

View File

@@ -1,25 +1,20 @@
import {parseFromValuesOrFunc} from "@/core/utils/utils"; import { parseFromValuesOrFunc } from "@/core/utils/utils";
import {TableRow} from "@mui/material"; import { TableRow } from "@mui/material";
import DataTable_TableHeadCell from "./TableHeadCell"; import DataTable_TableHeadCell from "./TableHeadCell";
const DataTable_TableHeadRow = ({ const DataTable_TableHeadRow = ({
columnVirtualizer, columnVirtualizer,
headerGroup, headerGroup,
table, table,
index, // Add index prop index, // Add index prop
...rest ...rest
}) => { }) => {
const { const {
options: { options: { enableStickyHeader, layoutMode, muiTableHeadRowProps },
enableStickyHeader,
layoutMode,
muiTableHeadRowProps,
},
} = table; } = table;
const {virtualColumns, virtualPaddingLeft, virtualPaddingRight} = const { virtualColumns, virtualPaddingLeft, virtualPaddingRight } = columnVirtualizer ?? {};
columnVirtualizer ?? {};
const backgroundColor = index % 2 === 0 ? '#015688' : '#ff5c0f'; const backgroundColor = index % 2 === 0 ? "#015688" : "#ff5c0f";
const tableRowProps = { const tableRowProps = {
...parseFromValuesOrFunc(muiTableHeadRowProps, { ...parseFromValuesOrFunc(muiTableHeadRowProps, {
@@ -27,20 +22,23 @@ const DataTable_TableHeadRow = ({
table, table,
}), }),
...rest, ...rest,
sx: (theme) => ({ // Access theme from the sx function sx: (theme) => ({
// Access theme from the sx function
...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}), ...(parseFromValuesOrFunc(muiTableHeadRowProps?.sx, theme) || {}),
backgroundColor, // Apply background color backgroundColor, // Apply background color
display: layoutMode?.startsWith('grid') ? 'flex' : undefined, display: layoutMode?.startsWith("grid") ? "flex" : undefined,
position: enableStickyHeader && layoutMode === 'semantic' ? 'sticky' : 'relative', position: enableStickyHeader && layoutMode === "semantic" ? "sticky" : "relative",
top: 0, top: 0,
}), }),
}; };
return ( return (
<TableRow {...tableRowProps}> <TableRow {...tableRowProps}>
{virtualPaddingLeft && <th style={{display: 'flex', width: virtualPaddingLeft}}/>} {virtualPaddingLeft && <th style={{ display: "flex", width: virtualPaddingLeft }} />}
{(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader, staticColumnIndex) => { {(virtualColumns ?? headerGroup.headers).map((headerOrVirtualHeader, staticColumnIndex) => {
const header = columnVirtualizer ? headerGroup.headers[headerOrVirtualHeader.index] : headerOrVirtualHeader; const header = columnVirtualizer
? headerGroup.headers[headerOrVirtualHeader.index]
: headerOrVirtualHeader;
return header ? ( return header ? (
<DataTable_TableHeadCell <DataTable_TableHeadCell
@@ -52,9 +50,9 @@ const DataTable_TableHeadRow = ({
/> />
) : null; ) : null;
})} })}
{virtualPaddingRight && <th style={{display: 'flex', width: virtualPaddingRight}}/>} {virtualPaddingRight && <th style={{ display: "flex", width: virtualPaddingRight }} />}
</TableRow> </TableRow>
); );
}; };
export default DataTable_TableHeadRow; export default DataTable_TableHeadRow;

View File

@@ -4,9 +4,9 @@ import DataTableProvider from "@/lib/contexts/DataTable";
const DataTable = (props) => { const DataTable = (props) => {
return ( return (
<DataTableProvider> <DataTableProvider>
<DataTable_Main {...props}/> <DataTable_Main {...props} />
</DataTableProvider> </DataTableProvider>
); );
}; };
export default DataTable; export default DataTable;

View File

@@ -67,8 +67,7 @@ export const FA_DATATABLE_LOCALIZATION = {
rowsPerPage: "ردیف در هر صفحه", rowsPerPage: "ردیف در هر صفحه",
save: "ذخیره", save: "ذخیره",
search: "جستجو", search: "جستجو",
selectedCountOfRowCountRowsSelected: selectedCountOfRowCountRowsSelected: "{selectedCount} از {rowCount} ردیف انتخاب شده",
"{selectedCount} از {rowCount} ردیف انتخاب شده",
select: "انتخاب", select: "انتخاب",
showAll: "نمایش همه", showAll: "نمایش همه",
showAllColumns: "نمایش همه ستون‌ها", showAllColumns: "نمایش همه ستون‌ها",
@@ -89,4 +88,4 @@ export const FA_DATATABLE_LOCALIZATION = {
unpin: "رها کردن", unpin: "رها کردن",
unpinAll: "رها کردن همه", unpinAll: "رها کردن همه",
unsorted: "بدون مرتب سازی", unsorted: "بدون مرتب سازی",
}; };

View File

@@ -1,12 +1,6 @@
import { Box, IconButton, ListItemIcon, MenuItem } from "@mui/material"; import { Box, IconButton, ListItemIcon, MenuItem } from "@mui/material";
const DataTable_ActionMenuItem = ({ const DataTable_ActionMenuItem = ({ icon, label, onOpenSubMenu, table, ...rest }) => {
icon,
label,
onOpenSubMenu,
table,
...rest
}) => {
const { const {
options: { options: {
icons: { ArrowRightIcon }, icons: { ArrowRightIcon },
@@ -16,35 +10,29 @@ const DataTable_ActionMenuItem = ({
return ( return (
<MenuItem <MenuItem
sx={{ sx={{
alignItems: 'center', alignItems: "center",
justifyContent: 'space-between', justifyContent: "space-between",
minWidth: '120px', minWidth: "120px",
my: 0, my: 0,
py: '6px', py: "6px",
}} }}
{...rest} {...rest}
> >
<Box <Box
sx={{ sx={{
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
}} }}
> >
<ListItemIcon>{icon}</ListItemIcon> <ListItemIcon>{icon}</ListItemIcon>
{label} {label}
</Box> </Box>
{onOpenSubMenu && ( {onOpenSubMenu && (
<IconButton <IconButton onClick={onOpenSubMenu} onMouseEnter={onOpenSubMenu} size="small" sx={{ p: 0 }}>
onClick={onOpenSubMenu}
onMouseEnter={onOpenSubMenu}
size="small"
sx={{ p: 0 }}
>
<ArrowRightIcon /> <ArrowRightIcon />
</IconButton> </IconButton>
)} )}
</MenuItem> </MenuItem>
); );
};
} export default DataTable_ActionMenuItem;
export default DataTable_ActionMenuItem

View File

@@ -2,10 +2,7 @@ import { parseFromValuesOrFunc } from "@/core/utils/utils";
import { Menu } from "@mui/material"; import { Menu } from "@mui/material";
import DataTable_ActionMenuItem from "./ActionMenuItem"; import DataTable_ActionMenuItem from "./ActionMenuItem";
const DataTable_CellActionMenu = ({ const DataTable_CellActionMenu = ({ table, ...rest }) => {
table,
...rest
}) => {
const { const {
getState, getState,
options: { options: {
@@ -32,12 +29,11 @@ const DataTable_CellActionMenu = ({
}; };
const internalMenuItems = [ const internalMenuItems = [
(parseFromValuesOrFunc(enableClickToCopy, cell) === 'context-menu' || (parseFromValuesOrFunc(enableClickToCopy, cell) === "context-menu" ||
parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === parseFromValuesOrFunc(columnDef.enableClickToCopy, cell) === "context-menu") && (
'context-menu') && (
<DataTable_ActionMenuItem <DataTable_ActionMenuItem
icon={<ContentCopy />} icon={<ContentCopy />}
key={'mrt-copy'} key={"mrt-copy"}
label={localization.copy} label={localization.copy}
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();
@@ -47,10 +43,10 @@ const DataTable_CellActionMenu = ({
table={table} table={table}
/> />
), ),
parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === 'cell' && ( parseFromValuesOrFunc(enableEditing, row) && editDisplayMode === "cell" && (
<DataTable_ActionMenuItem <DataTable_ActionMenuItem
icon={<EditIcon />} icon={<EditIcon />}
key={'mrt-edit'} key={"mrt-edit"}
label={localization.edit} label={localization.edit}
onClick={() => { onClick={() => {
openEditingCell({ cell, table }); openEditingCell({ cell, table });
@@ -71,14 +67,13 @@ const DataTable_CellActionMenu = ({
}; };
const menuItems = const menuItems =
columnDef.renderCellActionMenuItems?.(renderActionProps) ?? columnDef.renderCellActionMenuItems?.(renderActionProps) ?? renderCellActionMenuItems?.(renderActionProps);
renderCellActionMenuItems?.(renderActionProps);
return ( return (
(!!menuItems?.length || !!internalMenuItems?.length) && ( (!!menuItems?.length || !!internalMenuItems?.length) && (
<Menu <Menu
MenuListProps={{ MenuListProps={{
dense: density === 'compact', dense: density === "compact",
sx: { sx: {
backgroundColor: menuBackgroundColor, backgroundColor: menuBackgroundColor,
}, },
@@ -95,6 +90,5 @@ const DataTable_CellActionMenu = ({
</Menu> </Menu>
) )
); );
};
} export default DataTable_CellActionMenu;
export default DataTable_CellActionMenu

View File

@@ -2,11 +2,7 @@ import { Box, Button, Divider, Menu } from "@mui/material";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import DataTable_ShowHideColumnsMenuItems from "./ShowHideColumnsMenuItems"; import DataTable_ShowHideColumnsMenuItems from "./ShowHideColumnsMenuItems";
const DataTable_ShowHideColumnsMenu = ({ anchorEl, const DataTable_ShowHideColumnsMenu = ({ anchorEl, setAnchorEl, table, ...rest }) => {
setAnchorEl,
table,
...rest
}) => {
const { const {
getAllColumns, getAllColumns,
getAllLeafColumns, getAllLeafColumns,
@@ -36,14 +32,11 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
const allColumns = useMemo(() => { const allColumns = useMemo(() => {
const columns = getAllColumns(); const columns = getAllColumns();
if ( if (columnOrder.length > 0 && !columns.some((col) => col.columnDef.columnDefType === "group")) {
columnOrder.length > 0 &&
!columns.some((col) => col.columnDef.columnDefType === 'group')
) {
return [ return [
...getLeftLeafColumns(), ...getLeftLeafColumns(),
...Array.from(new Set(columnOrder)).map((colId) => ...Array.from(new Set(columnOrder)).map((colId) =>
getCenterLeafColumns().find((col) => col?.id === colId), getCenterLeafColumns().find((col) => col?.id === colId)
), ),
...getRightLeafColumns(), ...getRightLeafColumns(),
].filter(Boolean); ].filter(Boolean);
@@ -58,16 +51,14 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
getRightLeafColumns(), getRightLeafColumns(),
]); ]);
const isNestedColumns = allColumns.some( const isNestedColumns = allColumns.some((col) => col.columnDef.columnDefType === "group");
(col) => col.columnDef.columnDefType === 'group',
);
const [hoveredColumn, setHoveredColumn] = useState(null); const [hoveredColumn, setHoveredColumn] = useState(null);
return ( return (
<Menu <Menu
MenuListProps={{ MenuListProps={{
dense: density === 'compact', dense: density === "compact",
sx: { sx: {
backgroundColor: menuBackgroundColor, backgroundColor: menuBackgroundColor,
}, },
@@ -80,44 +71,29 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
> >
<Box <Box
sx={{ sx={{
display: 'flex', display: "flex",
justifyContent: 'space-between', justifyContent: "space-between",
p: '0.5rem', p: "0.5rem",
pt: 0, pt: 0,
}} }}
> >
{enableHiding && ( {enableHiding && (
<Button <Button disabled={!getIsSomeColumnsVisible()} onClick={() => handleToggleAllColumns(false)}>
disabled={!getIsSomeColumnsVisible()}
onClick={() => handleToggleAllColumns(false)}
>
{localization.hideAll} {localization.hideAll}
</Button> </Button>
)} )}
{enableColumnOrdering && ( {enableColumnOrdering && (
<Button <Button onClick={() => table.setColumnOrder(getDefaultColumnOrderIds(table.options, true))}>
onClick={() =>
table.setColumnOrder(
getDefaultColumnOrderIds(table.options, true),
)
}
>
{localization.resetOrder} {localization.resetOrder}
</Button> </Button>
)} )}
{enableColumnPinning && ( {enableColumnPinning && (
<Button <Button disabled={!getIsSomeColumnsPinned()} onClick={() => table.resetColumnPinning(true)}>
disabled={!getIsSomeColumnsPinned()}
onClick={() => table.resetColumnPinning(true)}
>
{localization.unpinAll} {localization.unpinAll}
</Button> </Button>
)} )}
{enableHiding && ( {enableHiding && (
<Button <Button disabled={getIsAllColumnsVisible()} onClick={() => handleToggleAllColumns(true)}>
disabled={getIsAllColumnsVisible()}
onClick={() => handleToggleAllColumns(true)}
>
{localization.showAll} {localization.showAll}
</Button> </Button>
)} )}
@@ -136,5 +112,5 @@ const DataTable_ShowHideColumnsMenu = ({ anchorEl,
))} ))}
</Menu> </Menu>
); );
} };
export default DataTable_ShowHideColumnsMenu export default DataTable_ShowHideColumnsMenu;

View File

@@ -30,7 +30,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
const switchChecked = column.getIsVisible(); const switchChecked = column.getIsVisible();
const handleToggleColumnHidden = (column) => { const handleToggleColumnHidden = (column) => {
if (columnDefType === 'group') { if (columnDefType === "group") {
column?.columns?.forEach?.((childColumn) => { column?.columns?.forEach?.((childColumn) => {
childColumn.toggleVisibility(!switchChecked); childColumn.toggleVisibility(!switchChecked);
}); });
@@ -78,29 +78,29 @@ const DataTable_ShowHideColumnsMenuItems = ({
ref={menuItemRef} ref={menuItemRef}
{...rest} {...rest}
sx={(theme) => ({ sx={(theme) => ({
alignItems: 'center', alignItems: "center",
justifyContent: 'flex-start', justifyContent: "flex-start",
my: 0, my: 0,
opacity: isDragging ? 0.5 : 1, opacity: isDragging ? 0.5 : 1,
outline: isDragging outline: isDragging
? `2px dashed ${theme.palette.grey[500]}` ? `2px dashed ${theme.palette.grey[500]}`
: hoveredColumn?.id === column.id : hoveredColumn?.id === column.id
? `2px dashed ${draggingBorderColor}` ? `2px dashed ${draggingBorderColor}`
: 'none', : "none",
outlineOffset: '-2px', outlineOffset: "-2px",
pl: `${(column.depth + 0.5) * 2}rem`, pl: `${(column.depth + 0.5) * 2}rem`,
py: '6px', py: "6px",
...(parseFromValuesOrFunc(rest?.sx, theme)), ...parseFromValuesOrFunc(rest?.sx, theme),
})} })}
> >
<Box <Box
sx={{ sx={{
display: 'flex', display: "flex",
flexWrap: 'nowrap', flexWrap: "nowrap",
gap: '8px', gap: "8px",
}} }}
> >
{columnDefType !== 'group' && {columnDefType !== "group" &&
enableColumnOrdering && enableColumnOrdering &&
!isNestedColumns && !isNestedColumns &&
(columnDef.enableColumnOrdering !== false ? ( (columnDef.enableColumnOrdering !== false ? (
@@ -110,7 +110,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
table={table} table={table}
/> />
) : ( ) : (
<Box sx={{ width: '28px' }} /> <Box sx={{ width: "28px" }} />
))} ))}
{enableHiding ? ( {enableHiding ? (
<FormControlLabel <FormControlLabel
@@ -119,15 +119,12 @@ const DataTable_ShowHideColumnsMenuItems = ({
typography: { typography: {
sx: { sx: {
mb: 0, mb: 0,
opacity: columnDefType !== 'display' ? 1 : 0.5, opacity: columnDefType !== "display" ? 1 : 0.5,
}, },
}, },
}} }}
control={ control={
<Tooltip <Tooltip {...getCommonTooltipProps()} title={localization.toggleVisibility}>
{...getCommonTooltipProps()}
title={localization.toggleVisibility}
>
<Switch /> <Switch />
</Tooltip> </Tooltip>
} }
@@ -136,9 +133,7 @@ const DataTable_ShowHideColumnsMenuItems = ({
onChange={() => handleToggleColumnHidden(column)} onChange={() => handleToggleColumnHidden(column)}
/> />
) : ( ) : (
<Typography sx={{ alignSelf: 'center' }}> <Typography sx={{ alignSelf: "center" }}>{columnDef.header}</Typography>
{columnDef.header}
</Typography>
)} )}
</Box> </Box>
</MenuItem> </MenuItem>
@@ -155,6 +150,5 @@ const DataTable_ShowHideColumnsMenuItems = ({
))} ))}
</> </>
); );
};
} export default DataTable_ShowHideColumnsMenuItems;
export default DataTable_ShowHideColumnsMenuItems;

View File

@@ -1,14 +1,14 @@
"use client" "use client";
import {IconButton, Tooltip} from '@mui/material'; import { IconButton, Tooltip } from "@mui/material";
import RestartAltIcon from '@mui/icons-material/RestartAlt'; import RestartAltIcon from "@mui/icons-material/RestartAlt";
import useTableSetting from "@/lib/hooks/useTableSetting"; import useTableSetting from "@/lib/hooks/useTableSetting";
import {useState} from "react"; import { useState } from "react";
function RefactorTable() { function RefactorTable() {
const {refactorAction} = useTableSetting(); const { refactorAction } = useTableSetting();
const [userId, setUserId] = useState(0); const [userId, setUserId] = useState(0);
const [pageName, setPageName] = useState('testPage'); const [pageName, setPageName] = useState("testPage");
const [tableName, setTableName] = useState('testTable'); const [tableName, setTableName] = useState("testTable");
const refactor = () => { const refactor = () => {
refactorAction(userId, pageName, tableName); refactorAction(userId, pageName, tableName);
@@ -17,12 +17,10 @@ function RefactorTable() {
return ( return (
<Tooltip title="بازنشانی اطلاعات"> <Tooltip title="بازنشانی اطلاعات">
<IconButton onClick={refactor} aria-label="refactor table"> <IconButton onClick={refactor} aria-label="refactor table">
<RestartAltIcon/> <RestartAltIcon />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
); );
} }
export default RefactorTable; export default RefactorTable;

View File

@@ -1,27 +1,27 @@
import {parseFromValuesOrFunc} from "@/core/utils/utils"; import { parseFromValuesOrFunc } from "@/core/utils/utils";
import {Paper} from "@mui/material"; import { Paper } from "@mui/material";
import DataTable_BottomToolbar from "../toolbar/BottomToolbar"; import DataTable_BottomToolbar from "../toolbar/BottomToolbar";
import DataTable_TopToolbar from "../toolbar/TopToolbar"; import DataTable_TopToolbar from "../toolbar/TopToolbar";
import DataTable_TableContainer from "./TableContainer"; import DataTable_TableContainer from "./TableContainer";
const DataTable_Paper = ({table, ...rest}) => { const DataTable_Paper = ({ table, ...rest }) => {
const { const {
getState, getState,
options: { options: {
enableBottomToolbar, enableBottomToolbar,
enableTopToolbar, enableTopToolbar,
mrtTheme: {baseBackgroundColor}, mrtTheme: { baseBackgroundColor },
muiTablePaperProps, muiTablePaperProps,
renderBottomToolbar, renderBottomToolbar,
renderTopToolbar, renderTopToolbar,
}, },
refs: {tablePaperRef}, refs: { tablePaperRef },
} = table; } = table;
const {isFullScreen} = getState(); const { isFullScreen } = getState();
const paperProps = { const paperProps = {
...parseFromValuesOrFunc(muiTablePaperProps, {table}), ...parseFromValuesOrFunc(muiTablePaperProps, { table }),
...rest, ...rest,
}; };
@@ -39,42 +39,44 @@ const DataTable_Paper = ({table, ...rest}) => {
style={{ style={{
...(isFullScreen ...(isFullScreen
? { ? {
bottom: 0, bottom: 0,
height: '100dvh', height: "100dvh",
left: 0, left: 0,
margin: 0, margin: 0,
maxHeight: '100dvh', maxHeight: "100dvh",
maxWidth: '100dvw', maxWidth: "100dvw",
padding: 0, padding: 0,
position: 'fixed', position: "fixed",
right: 0, right: 0,
top: 0, top: 0,
width: '100dvw', width: "100dvw",
zIndex: 999, zIndex: 999,
} }
: {}), : {}),
...paperProps?.style, ...paperProps?.style,
}} }}
sx={(theme) => ({ sx={(theme) => ({
backgroundColor: baseBackgroundColor, backgroundColor: baseBackgroundColor,
backgroundImage: 'unset', backgroundImage: "unset",
overflow: 'hidden', overflow: "hidden",
transition: 'all 100ms ease-in-out', transition: "all 100ms ease-in-out",
...(parseFromValuesOrFunc(paperProps?.sx, theme)), ...parseFromValuesOrFunc(paperProps?.sx, theme),
})} })}
> >
{enableTopToolbar && {enableTopToolbar &&
(parseFromValuesOrFunc(renderTopToolbar, {table}) ?? ( (parseFromValuesOrFunc(renderTopToolbar, { table }) ?? (
<DataTable_TopToolbar table={table} columns={paperProps.columns} table_url={paperProps.table_url} <DataTable_TopToolbar
user_id={paperProps.user_id} table={table}
page_name={paperProps.page_name} columns={paperProps.columns}
table_name={paperProps.table_name}/> table_url={paperProps.table_url}
user_id={paperProps.user_id}
page_name={paperProps.page_name}
table_name={paperProps.table_name}
/>
))} ))}
<DataTable_TableContainer table={table}/> <DataTable_TableContainer table={table} />
{enableBottomToolbar && {enableBottomToolbar &&
(parseFromValuesOrFunc(renderBottomToolbar, {table}) ?? ( (parseFromValuesOrFunc(renderBottomToolbar, { table }) ?? <DataTable_BottomToolbar table={table} />)}
<DataTable_BottomToolbar table={table}/>
))}
</Paper> </Paper>
); );
}; };

View File

@@ -5,10 +5,7 @@ import { useMemo } from "react";
import DataTable_TableBody, { Memo_DataTable_TableBody } from "../body/TableBody"; import DataTable_TableBody, { Memo_DataTable_TableBody } from "../body/TableBody";
import DataTable_TableHead from "../head/TableHead"; import DataTable_TableHead from "../head/TableHead";
const DataTable_Table = ({ const DataTable_Table = ({ table, ...rest }) => {
table,
...rest
}) => {
const { const {
getFlatHeaders, getFlatHeaders,
getState, getState,
@@ -23,8 +20,7 @@ const DataTable_Table = ({
renderCaption, renderCaption,
}, },
} = table; } = table;
const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } = const { columnSizing, columnSizingInfo, columnVisibility, isFullScreen } = getState();
getState();
const tableProps = { const tableProps = {
...parseFromValuesOrFunc(muiTableProps, { table }), ...parseFromValuesOrFunc(muiTableProps, { table }),
@@ -58,14 +54,14 @@ const DataTable_Table = ({
{...tableProps} {...tableProps}
style={{ ...columnSizeVars, ...tableProps?.style }} style={{ ...columnSizeVars, ...tableProps?.style }}
sx={(theme) => ({ sx={(theme) => ({
display: layoutMode?.startsWith('grid') ? 'grid' : undefined, display: layoutMode?.startsWith("grid") ? "grid" : undefined,
position: 'relative', position: "relative",
...(parseFromValuesOrFunc(tableProps?.sx, theme)), ...parseFromValuesOrFunc(tableProps?.sx, theme),
})} })}
> >
{!!Caption && <caption>{Caption}</caption>} {!!Caption && <caption>{Caption}</caption>}
{enableTableHead && <DataTable_TableHead {...commonTableGroupProps} />} {enableTableHead && <DataTable_TableHead {...commonTableGroupProps} />}
{memoMode === 'table-body' || columnSizingInfo.isResizingColumn ? ( {memoMode === "table-body" || columnSizingInfo.isResizingColumn ? (
<Memo_DataTable_TableBody {...commonTableGroupProps} /> <Memo_DataTable_TableBody {...commonTableGroupProps} />
) : ( ) : (
<DataTable_TableBody {...commonTableGroupProps} /> <DataTable_TableBody {...commonTableGroupProps} />
@@ -73,5 +69,5 @@ const DataTable_Table = ({
{/* {enableTableFooter && <MRT_TableFooter {...commonTableGroupProps} />} */} {/* {enableTableFooter && <MRT_TableFooter {...commonTableGroupProps} />} */}
</Table> </Table>
); );
} };
export default DataTable_Table export default DataTable_Table;

View File

@@ -5,31 +5,17 @@ import DataTable_CellActionMenu from "../menus/CellActionMenu";
import DataTable_Table from "./Table"; import DataTable_Table from "./Table";
import DataTable_TableLoadingOverlay from "./TableLoadingOverlay"; import DataTable_TableLoadingOverlay from "./TableLoadingOverlay";
const useIsomorphicLayoutEffect = const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
const DataTable_TableContainer = ({ const DataTable_TableContainer = ({ table, ...rest }) => {
table,
...rest
}) => {
const { const {
getState, getState,
options: { options: { enableCellActions, enableStickyHeader, muiTableContainerProps },
enableCellActions,
enableStickyHeader,
muiTableContainerProps,
},
refs: { bottomToolbarRef, tableContainerRef, topToolbarRef }, refs: { bottomToolbarRef, tableContainerRef, topToolbarRef },
} = table; } = table;
const { const { actionCell, isFullScreen, isLoading, showLoadingOverlay } = getState();
actionCell,
isFullScreen,
isLoading,
showLoadingOverlay,
} = getState();
const loading = const loading = showLoadingOverlay !== false && (isLoading || showLoadingOverlay);
showLoadingOverlay !== false && (isLoading || showLoadingOverlay);
const [totalToolbarHeight, setTotalToolbarHeight] = useState(0); const [totalToolbarHeight, setTotalToolbarHeight] = useState(0);
@@ -41,15 +27,9 @@ const DataTable_TableContainer = ({
}; };
useIsomorphicLayoutEffect(() => { useIsomorphicLayoutEffect(() => {
const topToolbarHeight = const topToolbarHeight = typeof document !== "undefined" ? topToolbarRef.current?.offsetHeight ?? 0 : 0;
typeof document !== 'undefined'
? topToolbarRef.current?.offsetHeight ?? 0
: 0;
const bottomToolbarHeight = const bottomToolbarHeight = typeof document !== "undefined" ? bottomToolbarRef?.current?.offsetHeight ?? 0 : 0;
typeof document !== 'undefined'
? bottomToolbarRef?.current?.offsetHeight ?? 0
: 0;
setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight); setTotalToolbarHeight(topToolbarHeight + bottomToolbarHeight);
}); });
@@ -57,7 +37,7 @@ const DataTable_TableContainer = ({
return ( return (
<TableContainer <TableContainer
aria-busy={loading} aria-busy={loading}
aria-describedby={loading ? 'mrt-progress' : undefined} aria-describedby={loading ? "mrt-progress" : undefined}
{...tableContainerProps} {...tableContainerProps}
ref={(node) => { ref={(node) => {
if (node) { if (node) {
@@ -69,19 +49,17 @@ const DataTable_TableContainer = ({
} }
}} }}
style={{ style={{
maxHeight: isFullScreen maxHeight: isFullScreen ? `calc(100vh - ${totalToolbarHeight}px)` : undefined,
? `calc(100vh - ${totalToolbarHeight}px)`
: undefined,
...tableContainerProps?.style, ...tableContainerProps?.style,
}} }}
sx={(theme) => ({ sx={(theme) => ({
maxHeight: enableStickyHeader maxHeight: enableStickyHeader
? `clamp(350px, calc(100vh - ${totalToolbarHeight}px), 9999px)` ? `clamp(350px, calc(100vh - ${totalToolbarHeight}px), 9999px)`
: undefined, : undefined,
maxWidth: '100%', maxWidth: "100%",
overflow: 'auto', overflow: "auto",
position: 'relative', position: "relative",
...(parseFromValuesOrFunc(tableContainerProps?.sx, theme)), ...parseFromValuesOrFunc(tableContainerProps?.sx, theme),
})} })}
> >
{loading ? <DataTable_TableLoadingOverlay table={table} /> : null} {loading ? <DataTable_TableLoadingOverlay table={table} /> : null}
@@ -89,6 +67,5 @@ const DataTable_TableContainer = ({
{enableCellActions && actionCell && <DataTable_CellActionMenu table={table} />} {enableCellActions && actionCell && <DataTable_CellActionMenu table={table} />}
</TableContainer> </TableContainer>
); );
};
} export default DataTable_TableContainer;
export default DataTable_TableContainer

View File

@@ -1,9 +1,6 @@
import { Box, CircularProgress } from "@mui/material"; import { Box, CircularProgress } from "@mui/material";
const DataTable_TableLoadingOverlay = ({ const DataTable_TableLoadingOverlay = ({ table, ...rest }) => {
table,
...rest
}) => {
const { const {
options: { options: {
localization, localization,
@@ -20,17 +17,17 @@ const DataTable_TableLoadingOverlay = ({
return ( return (
<Box <Box
sx={{ sx={{
alignItems: 'center', alignItems: "center",
backgroundColor: alpha(baseBackgroundColor, 0.5), backgroundColor: alpha(baseBackgroundColor, 0.5),
bottom: 0, bottom: 0,
display: 'flex', display: "flex",
justifyContent: 'center', justifyContent: "center",
left: 0, left: 0,
maxHeight: '100vh', maxHeight: "100vh",
position: 'absolute', position: "absolute",
right: 0, right: 0,
top: 0, top: 0,
width: '100%', width: "100%",
zIndex: 3, zIndex: 3,
}} }}
> >
@@ -43,6 +40,5 @@ const DataTable_TableLoadingOverlay = ({
)} )}
</Box> </Box>
); );
};
} export default DataTable_TableLoadingOverlay;
export default DataTable_TableLoadingOverlay

View File

@@ -3,23 +3,15 @@ import { Box, alpha, useMediaQuery } from "@mui/material";
import DataTable_LinearProgressBar from "./LinearProgressBar"; import DataTable_LinearProgressBar from "./LinearProgressBar";
import DataTable_TablePagination from "./TablePagination"; import DataTable_TablePagination from "./TablePagination";
const DataTable_BottomToolbar = ({ const DataTable_BottomToolbar = ({ table, ...rest }) => {
table,
...rest
}) => {
const { const {
getState, getState,
options: { options: { enablePagination, muiBottomToolbarProps, positionPagination, renderBottomToolbarCustomActions },
enablePagination,
muiBottomToolbarProps,
positionPagination,
renderBottomToolbarCustomActions,
},
refs: { bottomToolbarRef }, refs: { bottomToolbarRef },
} = table; } = table;
const { isFullScreen } = getState(); const { isFullScreen } = getState();
const isMobile = useMediaQuery('(max-width:720px)'); const isMobile = useMediaQuery("(max-width:720px)");
const toolbarProps = { const toolbarProps = {
...parseFromValuesOrFunc(muiBottomToolbarProps, { table }), ...parseFromValuesOrFunc(muiBottomToolbarProps, { table }),
...rest, ...rest,
@@ -40,49 +32,41 @@ const DataTable_BottomToolbar = ({
}} }}
sx={(theme) => ({ sx={(theme) => ({
...getCommonToolbarStyles({ table, theme }), ...getCommonToolbarStyles({ table, theme }),
bottom: isFullScreen ? '0' : undefined, bottom: isFullScreen ? "0" : undefined,
boxShadow: `0 1px 2px -1px ${alpha( boxShadow: `0 1px 2px -1px ${alpha(theme.palette.grey[700], 0.5)} inset`,
theme.palette.grey[700],
0.5,
)} inset`,
left: 0, left: 0,
position: isFullScreen ? 'fixed' : 'relative', position: isFullScreen ? "fixed" : "relative",
right: 0, right: 0,
...(parseFromValuesOrFunc(toolbarProps?.sx, theme)), ...parseFromValuesOrFunc(toolbarProps?.sx, theme),
})} })}
> >
<DataTable_LinearProgressBar isTopToolbar={false} table={table} /> <DataTable_LinearProgressBar isTopToolbar={false} table={table} />
<Box <Box
sx={{ sx={{
alignItems: 'center', alignItems: "center",
boxSizing: 'border-box', boxSizing: "border-box",
display: 'flex', display: "flex",
justifyContent: 'space-between', justifyContent: "space-between",
p: '0.5rem', p: "0.5rem",
width: '100%', width: "100%",
}} }}
> >
{renderBottomToolbarCustomActions ? ( {renderBottomToolbarCustomActions ? renderBottomToolbarCustomActions({ table }) : <span />}
renderBottomToolbarCustomActions({ table })
) : (
<span />
)}
<Box <Box
sx={{ sx={{
display: 'flex', display: "flex",
justifyContent: 'flex-end', justifyContent: "flex-end",
position: stackAlertBanner ? 'relative' : 'absolute', position: stackAlertBanner ? "relative" : "absolute",
right: 0, right: 0,
top: 0, top: 0,
}} }}
> >
{enablePagination && {enablePagination && ["both", "bottom"].includes(positionPagination ?? "") && (
['both', 'bottom'].includes(positionPagination ?? '') && ( <DataTable_TablePagination position="bottom" table={table} />
<DataTable_TablePagination position="bottom" table={table} /> )}
)}
</Box> </Box>
</Box> </Box>
</Box> </Box>
); );
} };
export default DataTable_BottomToolbar export default DataTable_BottomToolbar;

View File

@@ -1,11 +1,7 @@
import { parseFromValuesOrFunc } from "@/core/utils/utils"; import { parseFromValuesOrFunc } from "@/core/utils/utils";
import { Collapse, LinearProgress } from "@mui/material"; import { Collapse, LinearProgress } from "@mui/material";
const DataTable_LinearProgressBar = ({ const DataTable_LinearProgressBar = ({ isTopToolbar, table, ...rest }) => {
isTopToolbar,
table,
...rest
}) => {
const { const {
getState, getState,
options: { muiLinearProgressProps }, options: { muiLinearProgressProps },
@@ -26,19 +22,19 @@ const DataTable_LinearProgressBar = ({
mountOnEnter mountOnEnter
sx={{ sx={{
bottom: isTopToolbar ? 0 : undefined, bottom: isTopToolbar ? 0 : undefined,
position: 'absolute', position: "absolute",
top: !isTopToolbar ? 0 : undefined, top: !isTopToolbar ? 0 : undefined,
width: '100%', width: "100%",
}} }}
unmountOnExit unmountOnExit
> >
<LinearProgress <LinearProgress
aria-busy="true" aria-busy="true"
aria-label="Loading" aria-label="Loading"
sx={{ position: 'relative' }} sx={{ position: "relative" }}
{...linearProgressProps} {...linearProgressProps}
/> />
</Collapse> </Collapse>
); );
} };
export default DataTable_LinearProgressBar export default DataTable_LinearProgressBar;

View File

@@ -1,16 +1,23 @@
import { flipIconStyles, getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils"; import { flipIconStyles, getCommonTooltipProps, parseFromValuesOrFunc } from "@/core/utils/utils";
import { useTheme } from "@emotion/react"; import { useTheme } from "@emotion/react";
import { Box, IconButton, InputLabel, MenuItem, Pagination, PaginationItem, Select, Tooltip, Typography, useMediaQuery } from "@mui/material"; import {
Box,
IconButton,
InputLabel,
MenuItem,
Pagination,
PaginationItem,
Select,
Tooltip,
Typography,
useMediaQuery,
} from "@mui/material";
const defaultRowsPerPage = [5, 10, 15, 20, 25, 30, 50, 100]; const defaultRowsPerPage = [5, 10, 15, 20, 25, 30, 50, 100];
const DataTable_TablePagination = ({ const DataTable_TablePagination = ({ position = "bottom", table, ...rest }) => {
position = 'bottom',
table,
...rest
}) => {
const theme = useTheme(); const theme = useTheme();
const isMobile = useMediaQuery('(max-width: 720px)'); const isMobile = useMediaQuery("(max-width: 720px)");
const { const {
getState, getState,
@@ -64,26 +71,21 @@ const DataTable_TablePagination = ({
<Box <Box
className="MuiTablePagination-root" className="MuiTablePagination-root"
sx={{ sx={{
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
flexWrap: 'wrap', flexWrap: "wrap",
gap: '8px', gap: "8px",
justifyContent: { md: 'space-between', sm: 'center' }, justifyContent: { md: "space-between", sm: "center" },
justifySelf: 'flex-end', justifySelf: "flex-end",
mt: mt: position === "top" && enableToolbarInternalActions && !showGlobalFilter ? "3rem" : undefined,
position === 'top' && position: "relative",
enableToolbarInternalActions && px: "8px",
!showGlobalFilter py: "12px",
? '3rem'
: undefined,
position: 'relative',
px: '8px',
py: '12px',
zIndex: 2, zIndex: 2,
}} }}
> >
{showRowsPerPage && ( {showRowsPerPage && (
<Box sx={{ alignItems: 'center', display: 'flex', gap: '8px' }}> <Box sx={{ alignItems: "center", display: "flex", gap: "8px" }}>
<InputLabel htmlFor="mrt-rows-per-page" sx={{ mb: 0 }}> <InputLabel htmlFor="mrt-rows-per-page" sx={{ mb: 0 }}>
{localization.rowsPerPage} {localization.rowsPerPage}
</InputLabel> </InputLabel>
@@ -92,22 +94,19 @@ const DataTable_TablePagination = ({
disableUnderline disableUnderline
disabled={disabled} disabled={disabled}
inputProps={{ inputProps={{
'aria-label': localization.rowsPerPage, "aria-label": localization.rowsPerPage,
id: 'mrt-rows-per-page', id: "mrt-rows-per-page",
}} }}
label={localization.rowsPerPage} label={localization.rowsPerPage}
onChange={(event) => onChange={(event) => table.setPageSize(+event.target.value)}
table.setPageSize(+(event.target.value))
}
sx={{ mb: 0 }} sx={{ mb: 0 }}
value={pageSize} value={pageSize}
variant="standard" variant="standard"
{...SelectProps} {...SelectProps}
> >
{rowsPerPageOptions.map((option) => { {rowsPerPageOptions.map((option) => {
const value = typeof option !== 'number' ? option.value : option; const value = typeof option !== "number" ? option.value : option;
const label = const label = typeof option !== "number" ? option.label : `${option}`;
typeof option !== 'number' ? option.label : `${option}`;
return ( return (
SelectProps?.children ?? SelectProps?.children ??
(SelectProps?.native ? ( (SelectProps?.native ? (
@@ -124,7 +123,7 @@ const DataTable_TablePagination = ({
</Select> </Select>
</Box> </Box>
)} )}
{paginationDisplayMode === 'pages' ? ( {paginationDisplayMode === "pages" ? (
<Pagination <Pagination
count={numberOfPages} count={numberOfPages}
disabled={disabled} disabled={disabled}
@@ -145,16 +144,18 @@ const DataTable_TablePagination = ({
showLastButton={showLastButton} showLastButton={showLastButton}
{...restPaginationProps} {...restPaginationProps}
/> />
) : paginationDisplayMode === 'default' ? ( ) : paginationDisplayMode === "default" ? (
<> <>
<Typography <Typography
align="center" align="center"
component="span" component="span"
sx={{ m: '0 4px', minWidth: '8ch' }} sx={{ m: "0 4px", minWidth: "8ch" }}
variant="body2" variant="body2"
>{`${lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString() >{`${
}-${lastRowIndex.toLocaleString()} ${localization.of lastRowIndex === 0 ? 0 : (firstRowIndex + 1).toLocaleString()
} ${totalRowCount.toLocaleString()}`}</Typography> }-${lastRowIndex.toLocaleString()} ${
localization.of
} ${totalRowCount.toLocaleString()}`}</Typography>
<Box gap="xs"> <Box gap="xs">
{showFirstButton && ( {showFirstButton && (
<Tooltip {...tooltipProps} title={localization.goToFirstPage}> <Tooltip {...tooltipProps} title={localization.goToFirstPage}>
@@ -213,5 +214,5 @@ const DataTable_TablePagination = ({
) : null} ) : null}
</Box> </Box>
); );
} };
export default DataTable_TablePagination export default DataTable_TablePagination;

View File

@@ -16,32 +16,29 @@ const DataTable_ToolbarInternalButtons = ({ table, ...rest }) => {
}, },
} = table; } = table;
return ( return (
<Box <Box
{...rest} {...rest}
sx={(theme) => ({ sx={(theme) => ({
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
zIndex: 3, zIndex: 3,
...(parseFromValuesOrFunc(rest?.sx, theme)), ...parseFromValuesOrFunc(rest?.sx, theme),
})} })}
> >
{renderToolbarInternalActions?.({ {renderToolbarInternalActions?.({
table, table,
}) ?? ( }) ?? (
<> <>
{enableFilters && {enableFilters && enableColumnFilters && columnFilterDisplayMode !== "popover" && (
enableColumnFilters && <DataTable_ToggleFiltersButton table={table} />
columnFilterDisplayMode !== 'popover' && ( )}
<DataTable_ToggleFiltersButton table={table} /> {(enableHiding || enableColumnOrdering || enableColumnPinning) && (
)} <DataTable_ShowHideColumnsButton table={table} />
{(enableHiding || enableColumnOrdering || enableColumnPinning) && ( )}
<DataTable_ShowHideColumnsButton table={table} /> </>
)} )}
</>
)}
</Box> </Box>
); );
} };
export default DataTable_ToolbarInternalButtons export default DataTable_ToolbarInternalButtons;

View File

@@ -1,12 +1,12 @@
import {getCommonToolbarStyles, parseFromValuesOrFunc} from "@/core/utils/utils"; import { getCommonToolbarStyles, parseFromValuesOrFunc } from "@/core/utils/utils";
import {Box, useMediaQuery} from "@mui/material"; import { Box, useMediaQuery } from "@mui/material";
import DataTable_LinearProgressBar from "./LinearProgressBar"; import DataTable_LinearProgressBar from "./LinearProgressBar";
import DataTable_TablePagination from "./TablePagination"; import DataTable_TablePagination from "./TablePagination";
import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons"; import DataTable_ToolbarInternalButtons from "./ToolbarInternalButtons";
import FilterColumn from "@/core/components/DataTable/filter"; import FilterColumn from "@/core/components/DataTable/filter";
import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable"; import RefactorTable from "@/core/components/DataTable/refactor/RefactorTable";
const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, table_name}) => { const DataTable_TopToolbar = ({ table, columns, table_url, user_id, page_name, table_name }) => {
const { const {
getState, getState,
options: { options: {
@@ -16,19 +16,16 @@ const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, ta
positionPagination, positionPagination,
renderTopToolbarCustomActions, renderTopToolbarCustomActions,
}, },
refs: {topToolbarRef}, refs: { topToolbarRef },
} = table; } = table;
const {isFullScreen, showGlobalFilter} = getState(); const { isFullScreen, showGlobalFilter } = getState();
const isMobile = useMediaQuery('(max-width:720px)'); const isMobile = useMediaQuery("(max-width:720px)");
const isTablet = useMediaQuery('(max-width:1024px)'); const isTablet = useMediaQuery("(max-width:1024px)");
const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, {table}); const toolbarProps = parseFromValuesOrFunc(muiTopToolbarProps, { table });
const stackAlertBanner = const stackAlertBanner = isMobile || !!renderTopToolbarCustomActions || (showGlobalFilter && isTablet);
isMobile ||
!!renderTopToolbarCustomActions ||
(showGlobalFilter && isTablet);
return ( return (
<Box <Box
@@ -41,51 +38,55 @@ const DataTable_TopToolbar = ({table, columns, table_url, user_id, page_name, ta
} }
}} }}
sx={(theme) => ({ sx={(theme) => ({
...getCommonToolbarStyles({table, theme}), ...getCommonToolbarStyles({ table, theme }),
position: isFullScreen ? 'sticky' : 'relative', position: isFullScreen ? "sticky" : "relative",
top: isFullScreen ? '0' : undefined, top: isFullScreen ? "0" : undefined,
...(parseFromValuesOrFunc(toolbarProps?.sx, theme)), ...parseFromValuesOrFunc(toolbarProps?.sx, theme),
})} })}
> >
<Box <Box
sx={{ sx={{
alignItems: 'flex-start', alignItems: "flex-start",
boxSizing: 'border-box', boxSizing: "border-box",
display: 'flex', display: "flex",
gap: '0.5rem', gap: "0.5rem",
justifyContent: 'space-between', justifyContent: "space-between",
p: '0.5rem', p: "0.5rem",
position: stackAlertBanner ? 'relative' : 'absolute', position: stackAlertBanner ? "relative" : "absolute",
right: 0, right: 0,
top: 0, top: 0,
width: '100%', width: "100%",
}} }}
> >
{renderTopToolbarCustomActions?.({table}) ?? <span/>} {renderTopToolbarCustomActions?.({ table }) ?? <span />}
{enableToolbarInternalActions && ( {enableToolbarInternalActions && (
<Box <Box
sx={{ sx={{
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
flexWrap: 'wrap-reverse', flexWrap: "wrap-reverse",
gap: '0.5rem', gap: "0.5rem",
justifyContent: 'flex-end', justifyContent: "flex-end",
}} }}
> >
<RefactorTable/> <RefactorTable />
<FilterColumn columns={columns} table_url={table_url} user_id={user_id} page_name={page_name} <FilterColumn
table_name={table_name}/> columns={columns}
<DataTable_ToolbarInternalButtons table={table}/> table_url={table_url}
user_id={user_id}
page_name={page_name}
table_name={table_name}
/>
<DataTable_ToolbarInternalButtons table={table} />
</Box> </Box>
)} )}
</Box> </Box>
{enablePagination && {enablePagination && ["both", "top"].includes(positionPagination ?? "") && (
['both', 'top'].includes(positionPagination ?? '') && ( <DataTable_TablePagination position="top" table={table} />
<DataTable_TablePagination position="top" table={table}/> )}
)} <DataTable_LinearProgressBar isTopToolbar table={table} />
<DataTable_LinearProgressBar isTopToolbar table={table}/>
</Box> </Box>
); );
} };
export default DataTable_TopToolbar export default DataTable_TopToolbar;

View File

@@ -1,47 +1,61 @@
'use client' "use client";
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from "@mui/icons-material/Save";
import {Box, Button, Typography} from "@mui/material"; import { Box, Button, Typography } from "@mui/material";
import DownloadIcon from '@mui/icons-material/Download'; import DownloadIcon from "@mui/icons-material/Download";
import {toast} from "react-toastify"; import { toast } from "react-toastify";
function AskForKeep({onSaveFilter}) {
function AskForKeep({ onSaveFilter }) {
const handleDismiss = () => { const handleDismiss = () => {
toast.dismiss({containerId: "filtering"}); toast.dismiss({ containerId: "filtering" });
}; };
return ( return (
<Box sx={{width: "100%"}}> <Box sx={{ width: "100%" }}>
<Box sx={{display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1}}> <Box
<Typography color="#155175" variant="subtitle1" sx={{fontWeight: "500"}}> sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
mb: 1,
}}
>
<Typography color="#155175" variant="subtitle1" sx={{ fontWeight: "500" }}>
ذخیره سازی اطلاعات ذخیره سازی اطلاعات
</Typography> </Typography>
<SaveIcon sx={{color: "#155175"}}/> <SaveIcon sx={{ color: "#155175" }} />
</Box> </Box>
<Box sx={{display: "flex", flexDirection: "column"}}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">آیا مایل به ذخیره فیلتر های اعمال شده برای دفعات بعد هستید؟</Typography>
آیا مایل به ذخیره فیلتر های اعمال شده برای دفعات بعد هستید؟
</Typography>
</Box> </Box>
<Box sx={{display: "flex", gap: 1, mt: 1}}> <Box sx={{ display: "flex", gap: 1, mt: 1 }}>
<Button variant="contained" onClick={handleDismiss} sx={{ <Button
backgroundColor: "#792626", variant="contained"
':hover': {backgroundColor: "#792626"}, onClick={handleDismiss}
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px", sx={{
}}>رد backgroundColor: "#792626",
کردن</Button> ":hover": { backgroundColor: "#792626" },
<Button variant="contained" component="label" endIcon={<DownloadIcon/>} boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
onClick={onSaveFilter} }}
sx={{ >
backgroundColor: "#155175", رد کردن
':hover': {backgroundColor: "#155175"}, </Button>
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px", <Button
}}>ذخیره variant="contained"
فیلتر</Button> component="label"
endIcon={<DownloadIcon />}
onClick={onSaveFilter}
sx={{
backgroundColor: "#155175",
":hover": { backgroundColor: "#155175" },
boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
}}
>
ذخیره فیلتر
</Button>
</Box> </Box>
</Box> </Box>
); );
} }
export default AskForKeep; export default AskForKeep;

View File

@@ -1,77 +1,53 @@
import SidebarSubitems from "@/core/components/SidebarSubitems"; import SidebarSubitems from "@/core/components/SidebarSubitems";
import { ExpandLess, ExpandMore } from "@mui/icons-material"; import { ExpandLess, ExpandMore } from "@mui/icons-material";
import { import { Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
Collapse,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
} from "@mui/material";
import Link from "next/link"; import Link from "next/link";
const SidebarListItems = ({ menuItem, dispatch }) => { const SidebarListItems = ({ menuItem, dispatch }) => {
return ( return (
<> <>
<ListItem disablePadding divider> <ListItem disablePadding divider>
<ListItemButton <ListItemButton
sx={{ py: 1, px: 0.5 }} sx={{ py: 1, px: 0.5 }}
disableGutters disableGutters
selected={menuItem.selected} selected={menuItem.selected}
component={menuItem.type === "page" ? Link : null} component={menuItem.type === "page" ? Link : null}
href={menuItem.type === "page" ? menuItem.route : null} href={menuItem.type === "page" ? menuItem.route : null}
onClick={() => { onClick={() => {
dispatch({ type: "COLLAPSE_MENU", id: menuItem.id }); dispatch({ type: "COLLAPSE_MENU", id: menuItem.id });
}} }}
> >
<ListItemIcon <ListItemIcon
sx={{ sx={{
minWidth: 0, minWidth: 0,
justifyContent: "center", justifyContent: "center",
color: "primary.main", color: "primary.main",
width: 40, width: 40,
height: 24, height: 24,
}} }}
> >
{menuItem.icon} {menuItem.icon}
</ListItemIcon> </ListItemIcon>
<ListItemText primary={menuItem.label} /> <ListItemText primary={menuItem.label} />
{menuItem.hasSubitems ? ( {menuItem.hasSubitems ? menuItem.showSubitems ? <ExpandLess /> : <ExpandMore /> : null}
menuItem.showSubitems ? ( </ListItemButton>
<ExpandLess /> </ListItem>
) : ( <Collapse in={menuItem.showSubitems} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
<ExpandMore /> {menuItem.hasSubitems ? (
) <List
) : null} disablePadding
</ListItemButton> dense
</ListItem> sx={{
<Collapse background: "#00000008",
in={menuItem.showSubitems} }}
timeout="auto" >
mountOnEnter={true} {menuItem.Subitems.map((subitem, index) => {
unmountOnExit={true} return <SidebarSubitems key={index} dispatch={dispatch} subitem={subitem} />;
> })}
{menuItem.hasSubitems ? ( </List>
<List ) : null}
disablePadding </Collapse>
dense </>
sx={{ );
background: "#00000008",
}}
>
{menuItem.Subitems.map((subitem, index) => {
return (
<SidebarSubitems
key={index}
dispatch={dispatch}
subitem={subitem}
/>
);
})}
</List>
) : null}
</Collapse>
</>
);
}; };
export default SidebarListItems; export default SidebarListItems;

View File

@@ -6,127 +6,119 @@ import { useEffect, useReducer, useState } from "react";
import { pageMenu } from "../utils/pageMenu"; import { pageMenu } from "../utils/pageMenu";
function reducer(state, action) { function reducer(state, action) {
switch (action.type) { switch (action.type) {
case "COLLAPSE_MENU": case "COLLAPSE_MENU":
return state.map((item) => return state.map((item) =>
action.id == item.id action.id == item.id
? { ? {
...item, ...item,
showSubitems: !item.showSubitems, showSubitems: !item.showSubitems,
} }
: item : item
); );
case "COLLAPSE_SUB_ITEMS": case "COLLAPSE_SUB_ITEMS":
return state.map((item) => { return state.map((item) => {
return item.hasSubitems return item.hasSubitems
? { ? {
...item, ...item,
Subitems: item.Subitems.map((subitem) => Subitems: item.Subitems.map((subitem) =>
action.id === subitem.id action.id === subitem.id
? { ? {
...subitem, ...subitem,
showSubitems: !subitem.showSubitems, showSubitems: !subitem.showSubitems,
} }
: subitem : subitem
), ),
} }
: item; : item;
}); });
case "COLLAPSE_SUB_SECOND_ITEMS": case "COLLAPSE_SUB_SECOND_ITEMS":
return state.map((item) => { return state.map((item) => {
return item.hasSubitems return item.hasSubitems
? { ? {
...item, ...item,
Subitems: item.Subitems.map((subitem) => { Subitems: item.Subitems.map((subitem) => {
return subitem.hasSubitems return subitem.hasSubitems
? { ? {
...subitem, ...subitem,
Subitems: subitem.Subitems.map((secondSubitem) => Subitems: subitem.Subitems.map((secondSubitem) =>
action.id === secondSubitem.id action.id === secondSubitem.id
? { ? {
...secondSubitem, ...secondSubitem,
showSubitems: !secondSubitem.showSubitems, showSubitems: !secondSubitem.showSubitems,
} }
: secondSubitem : secondSubitem
), ),
} }
: subitem; : subitem;
}), }),
} }
: item; : item;
}); });
case "SELECTED": case "SELECTED":
return state.map((item) => { return state.map((item) => {
return item.type === "page" return item.type === "page"
? { ? {
...item, ...item,
selected: action.route === item.route, selected: action.route === item.route,
showSubitems: item.route === action.route, showSubitems: item.route === action.route,
} }
: item.Subitems && Array.isArray(item.Subitems) : item.Subitems && Array.isArray(item.Subitems)
? { ? {
...item, ...item,
Subitems: item.Subitems.map((subitem) => { Subitems: item.Subitems.map((subitem) => {
return subitem.type === "page" return subitem.type === "page"
? { ? {
...subitem, ...subitem,
selected: action.route === subitem.route, selected: action.route === subitem.route,
showSubitems: subitem.route === action.route, showSubitems: subitem.route === action.route,
} }
: subitem.Subitems && Array.isArray(subitem.Subitems) : subitem.Subitems && Array.isArray(subitem.Subitems)
? { ? {
...subitem, ...subitem,
Subitems: subitem.Subitems.map((secondSubItem) => ({ Subitems: subitem.Subitems.map((secondSubItem) => ({
...secondSubItem, ...secondSubItem,
selected: secondSubItem.route === action.route, selected: secondSubItem.route === action.route,
})), })),
showSubitems: subitem.Subitems.some( showSubitems: subitem.Subitems.some(
(secondSubItem) => secondSubItem.route === action.route (secondSubItem) => secondSubItem.route === action.route
), ),
} }
: subitem; : subitem;
}), }),
showSubitems: item.Subitems.some( showSubitems: item.Subitems.some((subitem) => subitem.showSubitems),
(subitem) => subitem.showSubitems }
), : item;
} });
: item;
});
default: default:
throw new Error(); throw new Error();
} }
} }
const SidebarMenu = () => { const SidebarMenu = () => {
const [menuItems, dispatch] = useReducer(reducer, pageMenu); const [menuItems, dispatch] = useReducer(reducer, pageMenu);
const pathname = usePathname(); const pathname = usePathname();
const [selectedKey, setSelectedKey] = useState(null); const [selectedKey, setSelectedKey] = useState(null);
useEffect(() => { useEffect(() => {
dispatch({ type: "SELECTED", route: pathname }); dispatch({ type: "SELECTED", route: pathname });
setSelectedKey(pathname); setSelectedKey(pathname);
}, [pathname]); }, [pathname]);
useEffect(() => { useEffect(() => {
selectedKey && selectedKey &&
document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({ document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({
behavior: "smooth", behavior: "smooth",
block: "center", block: "center",
}); });
}, [selectedKey]); }, [selectedKey]);
return ( return (
<List disablePadding dense> <List disablePadding dense>
{menuItems.map((menuItem) => { {menuItems.map((menuItem) => {
return ( return <SidebarListItems dispatch={dispatch} key={menuItem.id} menuItem={menuItem} />;
<SidebarListItems })}
dispatch={dispatch} </List>
key={menuItem.id} );
menuItem={menuItem}
/>
);
})}
</List>
);
}; };
export default SidebarMenu; export default SidebarMenu;

View File

@@ -1,75 +1,51 @@
import { ExpandLess, ExpandMore } from "@mui/icons-material"; import { ExpandLess, ExpandMore } from "@mui/icons-material";
import { import { Collapse, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from "@mui/material";
Collapse,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
} from "@mui/material";
import Link from "next/link"; import Link from "next/link";
const SidebarSubitems = ({ subitem, dispatch }) => { const SidebarSubitems = ({ subitem, dispatch }) => {
return ( return (
<> <>
<ListItem disablePadding divider> <ListItem disablePadding divider>
<ListItemButton <ListItemButton
disableGutters disableGutters
sx={{ py: 1, px: 0.5, pl: 1 }} sx={{ py: 1, px: 0.5, pl: 1 }}
selected={subitem.selected} selected={subitem.selected}
component={subitem.type === "page" ? Link : null} component={subitem.type === "page" ? Link : null}
href={subitem.type === "page" ? subitem.route : null} href={subitem.type === "page" ? subitem.route : null}
onClick={() => { onClick={() => {
dispatch({ type: "COLLAPSE_SUB_ITEMS", id: subitem.id }); dispatch({ type: "COLLAPSE_SUB_ITEMS", id: subitem.id });
}} }}
> >
<ListItemIcon <ListItemIcon
sx={{ sx={{
minWidth: 0, minWidth: 0,
justifyContent: "center", justifyContent: "center",
width: 40, width: 40,
height: 24, height: 24,
}} }}
> >
{subitem.icon} {subitem.icon}
</ListItemIcon> </ListItemIcon>
<ListItemText primary={subitem.label} /> <ListItemText primary={subitem.label} />
{subitem.hasSubitems ? ( {subitem.hasSubitems ? subitem.showSubitems ? <ExpandLess /> : <ExpandMore /> : null}
subitem.showSubitems ? ( </ListItemButton>
<ExpandLess /> </ListItem>
) : ( <Collapse in={subitem.showSubitems} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
<ExpandMore /> {subitem.hasSubitems ? (
) <List
) : null} disablePadding
</ListItemButton> dense
</ListItem> sx={{
<Collapse background: "#00000008",
in={subitem.showSubitems} }}
timeout="auto" >
mountOnEnter={true} {subitem.Subitems.map((subSubitem, index) => {
unmountOnExit={true} return <SidebarSubitems key={index} dispatch={dispatch} subitem={subSubitem} />;
> })}
{subitem.hasSubitems ? ( </List>
<List ) : null}
disablePadding </Collapse>
dense </>
sx={{ );
background: "#00000008",
}}
>
{subitem.Subitems.map((subSubitem, index) => {
return (
<SidebarSubitems
key={index}
dispatch={dispatch}
subitem={subSubitem}
/>
);
})}
</List>
) : null}
</Collapse>
</>
);
}; };
export default SidebarSubitems; export default SidebarSubitems;

View File

@@ -3,189 +3,185 @@ import { Box, Typography } from "@mui/material";
import { Dangerous } from "@mui/icons-material"; import { Dangerous } from "@mui/icons-material";
export const errorServerToast = (toastContainer) => export const errorServerToast = (toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">{"The request failed due to an internal error."}</Typography>
{"The request failed due to an internal error."} </Box>
</Typography> </Box>
</Box> </Box>
</Box> ),
</Box> {
), icon: false,
{ containerId: toastContainer,
icon: false, autoClose: 5000,
containerId: toastContainer, hideProgressBar: true,
autoClose: 5000, pauseOnHover: true,
hideProgressBar: true, closeOnClick: false,
pauseOnHover: true, draggable: true,
closeOnClick: false, }
draggable: true, );
}
);
export const errorUnauthorizedToast = (toastContainer) => export const errorUnauthorizedToast = (toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">{"The user is not authorized to make the request."}</Typography>
{"The user is not authorized to make the request."} </Box>
</Typography> </Box>
</Box> </Box>
</Box> ),
</Box> {
), icon: false,
{ containerId: toastContainer,
icon: false, autoClose: 3000,
containerId: toastContainer, hideProgressBar: true,
autoClose: 3000, pauseOnHover: true,
hideProgressBar: true, closeOnClick: false,
pauseOnHover: true, draggable: true,
closeOnClick: false, }
draggable: true, );
}
);
export const errorLogicToast = (message, toastContainer) => export const errorLogicToast = (message, toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">
{message || {message ||
"The request was well-formed but was unable to be followed due to semantic errors."} "The request was well-formed but was unable to be followed due to semantic errors."}
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
</Box> </Box>
), ),
{ {
icon: false, icon: false,
containerId: toastContainer, containerId: toastContainer,
autoClose: false, autoClose: false,
closeOnClick: false, closeOnClick: false,
draggable: false, draggable: false,
} }
); );
export const errorValidationToast = (message, toastContainer) => export const errorValidationToast = (message, toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">
{message || {message ||
"The request was well-formed but was unable to be followed due to semantic errors."} "The request was well-formed but was unable to be followed due to semantic errors."}
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
</Box> </Box>
), ),
{ {
icon: false, icon: false,
containerId: toastContainer, containerId: toastContainer,
autoClose: false, autoClose: false,
closeOnClick: false, closeOnClick: false,
draggable: false, draggable: false,
} }
); );
export const errorTooManyToast = (toastContainer) => export const errorTooManyToast = (toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">
{"Too many requests have been sent within a given time span."} {"Too many requests have been sent within a given time span."}
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
</Box> </Box>
), ),
{ {
icon: false, icon: false,
containerId: toastContainer, containerId: toastContainer,
autoClose: false, autoClose: false,
closeOnClick: false, closeOnClick: false,
draggable: false, draggable: false,
} }
); );
export const errorClientToast = (toastContainer) => export const errorClientToast = (toastContainer) =>
toast.error( toast.error(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Dangerous color="error" sx={{ mr: 1.6 }} /> <Dangerous color="error" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">
{ {
"The API request is invalid or improperly formed. Consequently, the API server could not understand the request." "The API request is invalid or improperly formed. Consequently, the API server could not understand the request."
} }
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
</Box> </Box>
), ),
{ {
icon: false, icon: false,
containerId: toastContainer, containerId: toastContainer,
autoClose: false, autoClose: false,
closeOnClick: false, closeOnClick: false,
draggable: false, draggable: false,
} }
); );

View File

@@ -3,33 +3,31 @@ import { Box, Typography } from "@mui/material";
import { Beenhere } from "@mui/icons-material"; import { Beenhere } from "@mui/icons-material";
export const successToast = (toastContainer) => export const successToast = (toastContainer) =>
toast.success( toast.success(
() => ( () => (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
alignItems: "start", alignItems: "start",
justifyContent: "start", justifyContent: "start",
}} }}
> >
<Box sx={{ display: "flex", alignItems: "center" }}> <Box sx={{ display: "flex", alignItems: "center" }}>
<Beenhere color="success" sx={{ mr: 1.6 }} /> <Beenhere color="success" sx={{ mr: 1.6 }} />
<Box sx={{ display: "flex", flexDirection: "column" }}> <Box sx={{ display: "flex", flexDirection: "column" }}>
<Typography variant="caption"> <Typography variant="caption">{"Your operation was successful"}</Typography>
{"Your operation was successful"} </Box>
</Typography> </Box>
</Box> </Box>
</Box> ),
</Box> {
), icon: false,
{ containerId: toastContainer,
icon: false, autoClose: 3000,
containerId: toastContainer, hideProgressBar: true,
autoClose: 3000, pauseOnHover: true,
hideProgressBar: true, closeOnClick: false,
pauseOnHover: true, draggable: true,
closeOnClick: false, }
draggable: true, );
}
);

View File

@@ -1,22 +1,22 @@
'use client' "use client";
import { useAuth } from "@/lib/contexts/auth"; import { useAuth } from "@/lib/contexts/auth";
import { usePathname, useRouter } from "next/navigation"; import { usePathname, useRouter } from "next/navigation";
import { useEffect } from "react"; import { useEffect } from "react";
function WithAuthMiddleware({ children }) { function WithAuthMiddleware({ children }) {
const router = useRouter() const router = useRouter();
const pathName = usePathname() const pathName = usePathname();
const { isAuth, initAuthState } = useAuth(); const { isAuth, initAuthState } = useAuth();
useEffect(() => { useEffect(() => {
if (!initAuthState) return if (!initAuthState) return;
if (!isAuth) { if (!isAuth) {
router.replace(`${process.env.NEXT_PUBLIC_API_URL}/login?_back=${encodeURIComponent(pathName)}`) router.replace(`${process.env.NEXT_PUBLIC_API_URL}/login?_back=${encodeURIComponent(pathName)}`);
} }
}, [isAuth, initAuthState]) }, [isAuth, initAuthState]);
if (!initAuthState || !isAuth) return null; if (!initAuthState || !isAuth) return null;
return <>{children}</> return <>{children}</>;
} }
export default WithAuthMiddleware export default WithAuthMiddleware;

View File

@@ -1,16 +1,16 @@
'use client' "use client";
import createCache from "@emotion/cache"; import createCache from "@emotion/cache";
import {prefixer} from "stylis"; import { prefixer } from "stylis";
import stylisRTLPlugin from "stylis-plugin-rtl"; import stylisRTLPlugin from "stylis-plugin-rtl";
import {CacheProvider} from "@emotion/react"; import { CacheProvider } from "@emotion/react";
const cache = createCache({ const cache = createCache({
key: 'mui-rtl', key: "mui-rtl",
stylisPlugins: [prefixer, stylisRTLPlugin], stylisPlugins: [prefixer, stylisRTLPlugin],
}); });
const cacheProviderRtl = (props) => { const cacheProviderRtl = (props) => {
return <CacheProvider value={cache}>{props.children}</CacheProvider>; return <CacheProvider value={cache}>{props.children}</CacheProvider>;
} };
export default cacheProviderRtl export default cacheProviderRtl;

View File

@@ -1,4 +1,4 @@
'use client' "use client";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { import {
errorClientToast, errorClientToast,
@@ -6,56 +6,55 @@ import {
errorServerToast, errorServerToast,
errorTooManyToast, errorTooManyToast,
errorUnauthorizedToast, errorUnauthorizedToast,
errorValidationToast errorValidationToast,
} from "@/core/components/toasts/error"; } from "@/core/components/toasts/error";
const isServerError = status => status >= 500 && status <= 599; const isServerError = (status) => status >= 500 && status <= 599;
const isClientError = status => status >= 400 && status <= 499; const isClientError = (status) => status >= 400 && status <= 499;
const errorServer = (response, notification, toastContainer) => { const errorServer = (response, notification, toastContainer) => {
if (notification) errorServerToast(toastContainer) if (notification) errorServerToast(toastContainer);
} };
const errorClient = (response, notification, toastContainer) => { const errorClient = (response, notification, toastContainer) => {
switch (response.status) { switch (response.status) {
case 401: case 401:
if (notification) errorUnauthorizedToast(toastContainer) if (notification) errorUnauthorizedToast(toastContainer);
break; break;
case 422: case 422:
if ('type' in response.data) { if ("type" in response.data) {
if (Array.isArray(response.data.message)) { if (Array.isArray(response.data.message)) {
response.data.message.map((item) => { response.data.message.map((item) => {
if (notification) errorLogicToast(item, toastContainer) if (notification) errorLogicToast(item, toastContainer);
}) });
} else { } else {
if (notification) errorLogicToast(response.data.message, toastContainer) if (notification) errorLogicToast(response.data.message, toastContainer);
} }
break; break;
} }
if (notification) { if (notification) {
const errorsMap = Object.keys(response.data.errors) const errorsMap = Object.keys(response.data.errors);
const errorsArray = response.data.errors const errorsArray = response.data.errors;
errorsMap.map((item, index) => { errorsMap.map((item, index) => {
errorValidationToast(errorsArray[item][0], toastContainer); errorValidationToast(errorsArray[item][0], toastContainer);
}) });
} }
break; break;
case 429: case 429:
if (notification) errorTooManyToast(toastContainer) if (notification) errorTooManyToast(toastContainer);
break break;
default: default:
if (notification) errorClientToast(toastContainer) if (notification) errorClientToast(toastContainer);
break break;
} }
} };
export const errorResponse = (response, notification, toastContainer) => { export const errorResponse = (response, notification, toastContainer) => {
if (notification) toast.dismiss({ container: toastContainer }) if (notification) toast.dismiss({ container: toastContainer });
if (isServerError(response.status)) { if (isServerError(response.status)) {
errorServer(response, notification, toastContainer) errorServer(response, notification, toastContainer);
} else if (isClientError(response.status)) { } else if (isClientError(response.status)) {
errorClient(response, notification, toastContainer) errorClient(response, notification, toastContainer);
} }
} };

View File

@@ -7,4 +7,4 @@ export const flattenArrayOfObjects = (array, key) => {
} }
return acc; return acc;
}, []); }, []);
}; };

View File

@@ -2,346 +2,346 @@ import { AirlineSeatReclineNormal, Assessment, Repartition, Security, SpaceDashb
export const pageMenu = [ export const pageMenu = [
{ {
id: 'dashboard', id: "dashboard",
label: 'پیشخوان', label: "پیشخوان",
type: "page", type: "page",
route: "/dashboard", route: "/dashboard",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'userManagement', id: "userManagement",
label: 'مدیریت کاربران', label: "مدیریت کاربران",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management", route: process.env.NEXT_PUBLIC_API_URL + "/v2/user_management",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'projectsManagment', id: "projectsManagment",
label: 'پروژه های راهداری', label: "پروژه های راهداری",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'projectsManagmentFinance', id: "projectsManagmentFinance",
label: 'ثبت قرارداد و پروژه', label: "ثبت قرارداد و پروژه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/finance",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'projectsManagmentList', id: "projectsManagmentList",
label: 'لیست پروژه ها', label: "لیست پروژه ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/projects_list",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'projectsManagmentProposal', id: "projectsManagmentProposal",
label: 'پروژه های پیشنهادی', label: "پروژه های پیشنهادی",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/proposal",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'projectsManagmentLawmaker', id: "projectsManagmentLawmaker",
label: 'درخواست نمایندگان', label: "درخواست نمایندگان",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers", route: process.env.NEXT_PUBLIC_API_URL + "/v2/rahdari_projects/lawmakers",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'projectsManagmentMap', id: "projectsManagmentMap",
label: 'پراکندگی بر روی نقشه', label: "پراکندگی بر روی نقشه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=rahdari_projects",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'roadItemManagment', id: "roadItemManagment",
label: 'فعالیت های روزانه', label: "فعالیت های روزانه",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadItemManagmentSupervisor', id: "roadItemManagmentSupervisor",
label: 'ارزیابی', label: "ارزیابی",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadItemManagmentSupervisorCartable', id: "roadItemManagmentSupervisorCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/supervisor/cartable",
}, },
] ],
}, },
{ {
id: 'roadItemManagmentOparation', id: "roadItemManagmentOparation",
label: 'عملیات', label: "عملیات",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadItemManagmentOparationCreate', id: "roadItemManagmentOparationCreate",
label: 'ثبت فعالیت', label: "ثبت فعالیت",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/create",
}, },
{ {
id: 'roadItemManagmentOparationCartable', id: "roadItemManagmentOparationCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/operator/cartable",
}, },
] ],
}, },
{ {
id: 'roadItemManagmentMap', id: "roadItemManagmentMap",
label: 'پراکندگی بر روی نقشه', label: "پراکندگی بر روی نقشه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_items",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'roadItemManagmentReport', id: "roadItemManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_items/report",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'roadPatrolManagment', id: "roadPatrolManagment",
label: 'گشت راهداری و ترابری', label: "گشت راهداری و ترابری",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadPatrolManagmentSupervisor', id: "roadPatrolManagmentSupervisor",
label: 'ارزیابی', label: "ارزیابی",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadPatrolManagmentSupervisorCartable', id: "roadPatrolManagmentSupervisorCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/road_patrols/supervisor/cartable",
}, },
] ],
}, },
{ {
id: 'roadPatrolManagmentOparation', id: "roadPatrolManagmentOparation",
label: 'عملیات', label: "عملیات",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadPatrolManagmentOparationCreate', id: "roadPatrolManagmentOparationCreate",
label: 'ثبت اقدام', label: "ثبت اقدام",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/create",
}, },
{ {
id: 'roadPatrolManagmentOparationCartable', id: "roadPatrolManagmentOparationCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/operator/cartable",
}, },
] ],
}, },
{ {
id: 'roadPatrolManagmentMap', id: "roadPatrolManagmentMap",
label: 'پراکندگی بر روی نقشه', label: "پراکندگی بر روی نقشه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_patrols",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'roadPatrolManagmentReport', id: "roadPatrolManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_patrols/report",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'safetyAndPrivacyManagment', id: "safetyAndPrivacyManagment",
label: 'نگهداری حریم راه', label: "نگهداری حریم راه",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'safetyAndPrivacyManagmentOparation', id: "safetyAndPrivacyManagmentOparation",
label: 'عملیات', label: "عملیات",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'safetyAndPrivacyManagmentOparationCreate', id: "safetyAndPrivacyManagmentOparationCreate",
label: 'ثبت فعالیت', label: "ثبت فعالیت",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step", route: process.env.NEXT_PUBLIC_API_URL + "/safety_and_privacy/operator/first_step",
}, },
{ {
id: 'safetyAndPrivacyManagmentOparationCartable', id: "safetyAndPrivacyManagmentOparationCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/operator/cartable",
}, },
] ],
}, },
{ {
id: 'safetyAndPrivacyManagmentMap', id: "safetyAndPrivacyManagmentMap",
label: 'پراکندگی بر روی نقشه', label: "پراکندگی بر روی نقشه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=safety_and_privacy",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'safetyAndPrivacyManagmentReport', id: "safetyAndPrivacyManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report", route: process.env.NEXT_PUBLIC_API_URL + "/v2/safety_and_privacy/report",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'roadObservationsManagment', id: "roadObservationsManagment",
label: 'واکنش سریع', label: "واکنش سریع",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadObservationsManagmentSupervisor', id: "roadObservationsManagmentSupervisor",
label: 'ارزیابی', label: "ارزیابی",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadObservationsManagmentSupervisorCartable', id: "roadObservationsManagmentSupervisorCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/supervisor/cartable",
}, },
] ],
}, },
{ {
id: 'roadObservationsManagmentList', id: "roadObservationsManagmentList",
label: 'رسیدگی به شکایات', label: "رسیدگی به شکایات",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'roadObservationsManagmentOparation', id: "roadObservationsManagmentOparation",
label: 'عملیات', label: "عملیات",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'roadObservationsManagmentOparationCartable', id: "roadObservationsManagmentOparationCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/operator/cartable",
}, },
] ],
}, },
{ {
id: 'roadObservationsManagmentMap', id: "roadObservationsManagmentMap",
label: 'پراکندگی بر روی نقشه', label: "پراکندگی بر روی نقشه",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=road_observations",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'roadObservationsManagmentReport', id: "roadObservationsManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index", route: process.env.NEXT_PUBLIC_API_URL + "/v2/road_observations/report/index",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'winterCampManagment', id: "winterCampManagment",
label: 'قرارگاه زمستانی', label: "قرارگاه زمستانی",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'winterCampManagmentBlocking', id: "winterCampManagmentBlocking",
label: 'محور های انسدادی', label: "محور های انسدادی",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp", route: process.env.NEXT_PUBLIC_API_URL + "/v2/winter_camp",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'winterCampManagmentFirstRing', id: "winterCampManagmentFirstRing",
label: 'محور های حلقه اول', label: "محور های حلقه اول",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=camp",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
{ {
id: 'winterCampManagmentReport', id: "winterCampManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew", route: process.env.NEXT_PUBLIC_API_URL + "/v2/map?type=campNew",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
}, },
{ {
id: 'receiptManagment', id: "receiptManagment",
label: 'خسارات وارده بر ابنیه فنی و تاسیسات راه', label: "خسارات وارده بر ابنیه فنی و تاسیسات راه",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'receiptManagmentOparation', id: "receiptManagmentOparation",
label: 'عملیات', label: "عملیات",
type: "menu", type: "menu",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
hasSubitems: true, hasSubitems: true,
Subitems: [ Subitems: [
{ {
id: 'receiptManagmentOparationCartable', id: "receiptManagmentOparationCartable",
label: 'کارتابل', label: "کارتابل",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt",
}, },
] ],
}, },
{ {
id: 'receiptManagmentReport', id: "receiptManagmentReport",
label: 'گزارش ها', label: "گزارش ها",
type: "page", type: "page",
route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report", route: process.env.NEXT_PUBLIC_API_URL + "/v2/receipt/report",
icon: <Security sx={{ width: 'inherit', height: 'inherit' }} />, icon: <Security sx={{ width: "inherit", height: "inherit" }} />,
}, },
] ],
} },
// { // {
// id: "hello", // id: "hello",
// type: "menu", // type: "menu",
@@ -383,4 +383,4 @@ export const pageMenu = [
// hasSubitems: true, // hasSubitems: true,
// showSubitems: false // showSubitems: false
// }, // },
] ];

View File

@@ -1,4 +1,4 @@
const api = process.env.NEXT_PUBLIC_API_URL const api = process.env.NEXT_PUBLIC_API_URL;
export const GET_USER_ROUTE = api + '/webapi/user/get-permission' export const GET_USER_ROUTE = api + "/webapi/user/get-permission";
export const GET_LOGIN_ROUTE = api + '/test_login' export const GET_LOGIN_ROUTE = api + "/login_dev";

View File

@@ -1,10 +1,10 @@
'use client' "use client";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { successToast } from "@/core/components/toasts/success"; import { successToast } from "@/core/components/toasts/success";
export const successRequest = (notification, toastContainer) => { export const successRequest = (notification, toastContainer) => {
if (notification) { if (notification) {
toast.dismiss({ container: toastContainer }) toast.dismiss({ container: toastContainer });
successToast(toastContainer) successToast(toastContainer);
} }
} };

View File

@@ -1,22 +1,22 @@
'use client' "use client";
import { createTheme } from "@mui/material"; import { createTheme } from "@mui/material";
const theme = createTheme({ const theme = createTheme({
direction: 'rtl', direction: "rtl",
typography: { typography: {
fontFamily: `IRANSansFaNum, sans-serif`, fontFamily: `IRANSansFaNum, sans-serif`,
fontSize: 12 fontSize: 12,
}, },
palette: { palette: {
primary: { primary: {
main: '#2070af', main: "#2070af",
contrastText: '#fff' contrastText: "#fff",
}, },
primary2: { primary2: {
main: '#015688', main: "#015688",
contrastText: '#fff' contrastText: "#fff",
}, },
} },
}); });
export default theme export default theme;

View File

@@ -1,162 +1,120 @@
import { alpha, darken } from "@mui/material"; import { alpha, darken } from "@mui/material";
export const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, '_'); export const parseCSSVarId = (id) => id.replace(/[^a-zA-Z0-9]/g, "_");
export const parseFromValuesOrFunc = ( export const parseFromValuesOrFunc = (fn, arg) => (fn instanceof Function ? fn(arg) : fn);
fn,
arg
) => (fn instanceof Function ? fn(arg) : fn);
export const getCommonToolbarStyles = ({ export const getCommonToolbarStyles = ({ table }) => ({
table, alignItems: "flex-start",
}) => ({ backgroundColor: table.options.mrtTheme.baseBackgroundColor,
alignItems: 'flex-start', display: "grid",
backgroundColor: table.options.mrtTheme.baseBackgroundColor, flexWrap: "wrap-reverse",
display: 'grid', minHeight: "3.5rem",
flexWrap: 'wrap-reverse', overflow: "hidden",
minHeight: '3.5rem', position: "relative",
overflow: 'hidden', transition: "all 150ms ease-in-out",
position: 'relative', zIndex: 1,
transition: 'all 150ms ease-in-out',
zIndex: 1,
}); });
export const getCommonTooltipProps = ( export const getCommonTooltipProps = (placement) => ({
placement, disableInteractive: true,
) => ({ enterDelay: 500,
disableInteractive: true, enterNextDelay: 500,
enterDelay: 500, placement,
enterNextDelay: 500,
placement,
}); });
export const flipIconStyles = (theme) => export const flipIconStyles = (theme) =>
theme.direction === 'rtl' theme.direction === "rtl" ? { style: { transform: "scaleX(-1)" } } : undefined;
? { style: { transform: 'scaleX(-1)' } }
: undefined;
export const getCommonPinnedCellStyles = ({ export const getCommonPinnedCellStyles = ({ column, table, theme }) => {
column, const { baseBackgroundColor } = table.options.mrtTheme;
table, const isPinned = column?.getIsPinned();
theme,
}) => {
const { baseBackgroundColor } = table.options.mrtTheme;
const isPinned = column?.getIsPinned();
return { return {
'&[data-pinned="true"]': { '&[data-pinned="true"]': {
'&:before': { "&:before": {
backgroundColor: alpha( backgroundColor: alpha(darken(baseBackgroundColor, theme.palette.mode === "dark" ? 0.05 : 0.01), 0.97),
darken( boxShadow: column
baseBackgroundColor, ? isPinned === "left" && column.getIsLastColumn(isPinned)
theme.palette.mode === 'dark' ? 0.05 : 0.01, ? `-4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset`
), : isPinned === "right" && column.getIsFirstColumn(isPinned)
0.97, ? `4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset`
), : undefined
boxShadow: column : undefined,
? isPinned === 'left' && column.getIsLastColumn(isPinned) ...commonCellBeforeAfterStyles,
? `-4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` },
: isPinned === 'right' && column.getIsFirstColumn(isPinned) },
? `4px 0 4px -4px ${alpha(theme.palette.grey[700], 0.5)} inset` };
: undefined
: undefined,
...commonCellBeforeAfterStyles,
},
},
};
}; };
export const getCommonMRTCellStyles = ({ export const getCommonMRTCellStyles = ({ column, header, table, tableCellProps, theme }) => {
column, const {
header, getState,
table, options: { enableColumnVirtualization, layoutMode },
tableCellProps, } = table;
theme, const { draggingColumn } = getState();
}) => { const { columnDef } = column;
const { const { columnDefType } = columnDef;
getState,
options: { enableColumnVirtualization, layoutMode },
} = table;
const { draggingColumn } = getState();
const { columnDef } = column;
const { columnDefType } = columnDef;
const isColumnPinned = const isColumnPinned = columnDef.columnDefType !== "group" && column.getIsPinned();
columnDef.columnDefType !== 'group' && column.getIsPinned();
const widthStyles = { const widthStyles = {
minWidth: `max(calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId( minWidth: `max(calc(var(--${header ? "header" : "col"}-${parseCSSVarId(
header?.id ?? column.id, header?.id ?? column.id
)}-size) * 1px), ${columnDef.minSize ?? 30}px)`, )}-size) * 1px), ${columnDef.minSize ?? 30}px)`,
width: `calc(var(--${header ? 'header' : 'col'}-${parseCSSVarId( width: `calc(var(--${header ? "header" : "col"}-${parseCSSVarId(header?.id ?? column.id)}-size) * 1px)`,
header?.id ?? column.id, };
)}-size) * 1px)`,
};
if (layoutMode === 'grid') { if (layoutMode === "grid") {
widthStyles.flex = `${[0, false].includes(columnDef.grow) widthStyles.flex = `${
? 0 [0, false].includes(columnDef.grow)
: `var(--${header ? 'header' : 'col'}-${parseCSSVarId( ? 0
header?.id ?? column.id, : `var(--${header ? "header" : "col"}-${parseCSSVarId(header?.id ?? column.id)}-size)`
)}-size)` } 0 auto`;
} 0 auto`; } else if (layoutMode === "grid-no-grow") {
} else if (layoutMode === 'grid-no-grow') { widthStyles.flex = `${+(columnDef.grow || 0)} 0 auto`;
widthStyles.flex = `${+(columnDef.grow || 0)} 0 auto`;
}
const pinnedStyles = isColumnPinned
? {
...getCommonPinnedCellStyles({ column, table, theme }),
left:
isColumnPinned === 'left'
? `${column.getStart('left')}px`
: undefined,
opacity: 0.97,
position: 'sticky',
right:
isColumnPinned === 'right'
? `${column.getAfter('right')}px`
: undefined,
} }
: {};
return { const pinnedStyles = isColumnPinned
backgroundColor: 'inherit', ? {
backgroundImage: 'inherit', ...getCommonPinnedCellStyles({ column, table, theme }),
display: layoutMode?.startsWith('grid') ? 'flex' : undefined, left: isColumnPinned === "left" ? `${column.getStart("left")}px` : undefined,
justifyContent: opacity: 0.97,
columnDefType === 'group' position: "sticky",
? 'center' right: isColumnPinned === "right" ? `${column.getAfter("right")}px` : undefined,
: layoutMode?.startsWith('grid') }
? tableCellProps.align : {};
: undefined,
opacity: return {
table.getState().draggingColumn?.id === column.id || backgroundColor: "inherit",
table.getState().hoveredColumn?.id === column.id backgroundImage: "inherit",
? 0.5 display: layoutMode?.startsWith("grid") ? "flex" : undefined,
: 1, justifyContent:
position: 'relative', columnDefType === "group" ? "center" : layoutMode?.startsWith("grid") ? tableCellProps.align : undefined,
transition: enableColumnVirtualization opacity:
? 'none' table.getState().draggingColumn?.id === column.id || table.getState().hoveredColumn?.id === column.id
: `padding 150ms ease-in-out`, ? 0.5
zIndex: : 1,
column.getIsResizing() || draggingColumn?.id === column.id position: "relative",
? 2 transition: enableColumnVirtualization ? "none" : `padding 150ms ease-in-out`,
: columnDefType !== 'group' && isColumnPinned zIndex:
? 1 column.getIsResizing() || draggingColumn?.id === column.id
: 0, ? 2
...pinnedStyles, : columnDefType !== "group" && isColumnPinned
...widthStyles, ? 1
...(parseFromValuesOrFunc(tableCellProps?.sx, theme)), : 0,
}; ...pinnedStyles,
...widthStyles,
...parseFromValuesOrFunc(tableCellProps?.sx, theme),
};
}; };
export const commonCellBeforeAfterStyles = { export const commonCellBeforeAfterStyles = {
content: '""', content: '""',
height: '100%', height: "100%",
left: 0, left: 0,
position: 'absolute', position: "absolute",
top: 0, top: 0,
width: '100%', width: "100%",
zIndex: -1, zIndex: -1,
}; };

View File

@@ -1,15 +1,11 @@
import {createContext, useState} from "react"; import { createContext, useState } from "react";
export const DataTableContext = createContext(); export const DataTableContext = createContext();
const DataTableProvider = ({children}) => { const DataTableProvider = ({ children }) => {
const [filterData, setFilterData] = useState({}); const [filterData, setFilterData] = useState({});
return ( return <DataTableContext.Provider value={{ filterData, setFilterData }}>{children}</DataTableContext.Provider>;
<DataTableContext.Provider value={{filterData, setFilterData}}>
{children}
</DataTableContext.Provider>
);
}; };
export default DataTableProvider; export default DataTableProvider;

View File

@@ -1,12 +1,12 @@
'use client' "use client";
import { createContext, useCallback, useContext, useEffect, useReducer } from 'react'; import { createContext, useCallback, useContext, useEffect, useReducer } from "react";
import useRequest from '../hooks/useRequest'; import useRequest from "../hooks/useRequest";
import { GET_USER_ROUTE } from '@/core/utils/routes'; import { GET_USER_ROUTE } from "@/core/utils/routes";
const initAuth = { const initAuth = {
initAuthState: false, initAuthState: false,
isAuth: false, isAuth: false,
user: {} user: {},
}; };
const authReducer = (state, action) => { const authReducer = (state, action) => {
@@ -28,7 +28,7 @@ const AuthContext = createContext();
export const AuthProvider = ({ children }) => { export const AuthProvider = ({ children }) => {
const [state, dispatch] = useReducer(authReducer, initAuth); const [state, dispatch] = useReducer(authReducer, initAuth);
const request = useRequest() const request = useRequest();
const clearUser = useCallback(() => { const clearUser = useCallback(() => {
dispatch({ type: "CLEAR_USER" }); dispatch({ type: "CLEAR_USER" });
@@ -48,7 +48,7 @@ export const AuthProvider = ({ children }) => {
const getUser = useCallback(async () => { const getUser = useCallback(async () => {
try { try {
const { data } = await request(GET_USER_ROUTE, 'get') const { data } = await request(GET_USER_ROUTE, "get");
changeUser(data); changeUser(data);
changeAuthState(true); changeAuthState(true);
changeInitAuth(true); changeInitAuth(true);
@@ -62,15 +62,21 @@ export const AuthProvider = ({ children }) => {
}, [clearUser, changeUser, changeAuthState, changeInitAuth]); }, [clearUser, changeUser, changeAuthState, changeInitAuth]);
useEffect(() => { useEffect(() => {
getUser() getUser();
}, []) }, []);
return <AuthContext.Provider value={{ return (
user: state.user, <AuthContext.Provider
isAuth: state.isAuth, value={{
initAuthState: state.initAuthState, user: state.user,
getUser isAuth: state.isAuth,
}}>{children}</AuthContext.Provider>; initAuthState: state.initAuthState,
getUser,
}}
>
{children}
</AuthContext.Provider>
);
}; };
export const useAuth = () => useContext(AuthContext); export const useAuth = () => useContext(AuthContext);

View File

@@ -1,26 +1,26 @@
'use client' "use client";
import {createContext, useCallback, useEffect, useState} from "react"; import { createContext, useCallback, useEffect, useState } from "react";
export const TableSettingContext = createContext(); export const TableSettingContext = createContext();
export const TableSettingProvider = ({children}) => { export const TableSettingProvider = ({ children }) => {
const [settingStore, setSettingStore] = useState({}); const [settingStore, setSettingStore] = useState({});
useEffect(() => { useEffect(() => {
const _localStorage = localStorage.getItem("_setting-app") const _localStorage = localStorage.getItem("_setting-app");
if (_localStorage) { if (_localStorage) {
setSettingStore(JSON.parse(_localStorage)) setSettingStore(JSON.parse(_localStorage));
} }
}, []); }, []);
const hideAction = useCallback((user_id, page_name, table_name, settingValue, columns) => { const hideAction = useCallback((user_id, page_name, table_name, settingValue, columns) => {
updateSettingStorage(user_id, page_name, table_name, "hides", settingValue, columns); updateSettingStorage(user_id, page_name, table_name, "hides", settingValue, columns);
}, []) }, []);
const sortAction = useCallback((user_id, page_name, table_name, settingValue, columns) => { const sortAction = useCallback((user_id, page_name, table_name, settingValue, columns) => {
updateSettingStorage(user_id, page_name, table_name, "sorts", settingValue, columns); updateSettingStorage(user_id, page_name, table_name, "sorts", settingValue, columns);
}, []) }, []);
const filterAction = (user_id, page_name, table_name, settingValue, columns) => { const filterAction = (user_id, page_name, table_name, settingValue, columns) => {
updateSettingStorage(user_id, page_name, table_name, "filters", settingValue, columns); updateSettingStorage(user_id, page_name, table_name, "filters", settingValue, columns);
} };
const updateSettingStorage = (user_id, page_name, table_name, settingType, settingValue, columns) => { const updateSettingStorage = (user_id, page_name, table_name, settingType, settingValue, columns) => {
const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {};
const userSettings = prevLocalStorage[user_id] || {}; const userSettings = prevLocalStorage[user_id] || {};
@@ -30,7 +30,7 @@ export const TableSettingProvider = ({children}) => {
if (settingType === "sorts" || settingType === "filters") { if (settingType === "sorts" || settingType === "filters") {
newSettings = [...settingValue]; newSettings = [...settingValue];
} else { } else {
newSettings = {...tableSettings[settingType] || {}, ...settingValue}; newSettings = { ...(tableSettings[settingType] || {}), ...settingValue };
} }
const updatedLocalStorage = { const updatedLocalStorage = {
...prevLocalStorage, ...prevLocalStorage,
@@ -40,18 +40,21 @@ export const TableSettingProvider = ({children}) => {
...pageSettings, ...pageSettings,
[table_name]: { [table_name]: {
...tableSettings, ...tableSettings,
[settingType]: Array.isArray(settingValue) ? [...newSettings] : {...newSettings}, [settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings },
summary: SummaryTextMessage({ summary: SummaryTextMessage(
...tableSettings, {
[settingType]: Array.isArray(settingValue) ? [...newSettings] : {...newSettings}, ...tableSettings,
}, columns) [settingType]: Array.isArray(settingValue) ? [...newSettings] : { ...newSettings },
},
columns
),
}, },
}, },
}, },
}; };
localStorage.setItem("_setting-app", JSON.stringify(updatedLocalStorage)); localStorage.setItem("_setting-app", JSON.stringify(updatedLocalStorage));
setSettingStore(updatedLocalStorage); setSettingStore(updatedLocalStorage);
} };
const refactorAction = (user_id, page_name, table_name) => { const refactorAction = (user_id, page_name, table_name) => {
const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {}; const prevLocalStorage = JSON.parse(localStorage.getItem("_setting-app")) || {};
const userSettings = prevLocalStorage[user_id] || {}; const userSettings = prevLocalStorage[user_id] || {};
@@ -68,7 +71,7 @@ export const TableSettingProvider = ({children}) => {
}; };
localStorage.setItem("_setting-app", JSON.stringify(refactorData)); localStorage.setItem("_setting-app", JSON.stringify(refactorData));
setSettingStore(refactorData); setSettingStore(refactorData);
} };
const SummaryTextMessage = (values, columns) => { const SummaryTextMessage = (values, columns) => {
let SummaryText = ""; let SummaryText = "";
let HideText = ""; let HideText = "";
@@ -76,38 +79,35 @@ export const TableSettingProvider = ({children}) => {
let SortText = ""; let SortText = "";
if (values.sorts && values.sorts.length > 0) { if (values.sorts && values.sorts.length > 0) {
const _list = [] const _list = [];
for (const sort of values.sorts) { for (const sort of values.sorts) {
const _column = columns.find(column => column.id == sort.id) const _column = columns.find((column) => column.id == sort.id);
if (_column) if (_column) _list.push(`${_column.header}` + `(${sort.desc ? "نزولی" : "صعودی"})`);
_list.push(`${_column.header}` + `(${sort.desc ? "نزولی" : "صعودی"})`)
} }
if (_list.length > 0) if (_list.length > 0) SortText = " مرتب شده بر اساس : " + _list.join(", ");
SortText = " مرتب شده بر اساس : " + _list.join(", ")
} }
if (values.filters && values.filters.length > 0) { if (values.filters && values.filters.length > 0) {
const _list = [] const _list = [];
for (const filter of values.filters) { for (const filter of values.filters) {
const _column = columns.find(column => column.id == filter.id) const _column = columns.find((column) => column.id == filter.id);
if (_column) if (_column) _list.push(`${_column.header}`);
_list.push(`${_column.header}`)
} }
if (_list.length > 0) if (_list.length > 0) FilterText = " فیلتر شده بر اساس : " + _list.join(", ");
FilterText = " فیلتر شده بر اساس : " + _list.join(", ")
} }
if (values.hides) { if (values.hides) {
const hidesArray = Object.entries(values.hides).map((e) => ({id: e[0], value: e[1]})) const hidesArray = Object.entries(values.hides).map((e) => ({
id: e[0],
value: e[1],
}));
if (hidesArray.length > 0) { if (hidesArray.length > 0) {
const _list = [] const _list = [];
for (const hide of hidesArray) { for (const hide of hidesArray) {
if (hide.value) continue if (hide.value) continue;
const _column = columns.find(c => c.id == hide.id) const _column = columns.find((c) => c.id == hide.id);
if (_column) if (_column) _list.push(_column.header);
_list.push(_column.header)
} }
if (_list.length > 0) if (_list.length > 0) HideText = "ستون های مخفی شده : " + _list.join(", ");
HideText = "ستون های مخفی شده : " + _list.join(", ");
} }
} }
@@ -128,7 +128,7 @@ export const TableSettingProvider = ({children}) => {
} }
} }
if (FilterText) { if (FilterText) {
SummaryText += FilterText SummaryText += FilterText;
} }
} }
@@ -137,8 +137,15 @@ export const TableSettingProvider = ({children}) => {
return ( return (
<TableSettingContext.Provider <TableSettingContext.Provider
value={{settingStore, hideAction, sortAction, filterAction, refactorAction}}> value={{
settingStore,
hideAction,
sortAction,
filterAction,
refactorAction,
}}
>
{children} {children}
</TableSettingContext.Provider> </TableSettingContext.Provider>
); );
}; };

View File

@@ -1,9 +1,9 @@
import {useContext} from "react"; import { useContext } from "react";
import {DataTableContext} from "@/lib/contexts/DataTable"; import { DataTableContext } from "@/lib/contexts/DataTable";
const useTableSetting = () => { const useTableSetting = () => {
const {filterData, setFilterData} = useContext(DataTableContext); const { filterData, setFilterData } = useContext(DataTableContext);
return {filterData, setFilterData}; return { filterData, setFilterData };
}; };
export default useTableSetting; export default useTableSetting;

View File

@@ -5,38 +5,42 @@ import axios from "axios";
const defaultOptions = { const defaultOptions = {
data: {}, data: {},
requestOptions: { requestOptions: {
headers: {} headers: {},
}, },
notification: { notification: {
show: true, show: true,
success: false, success: false,
failed: true failed: true,
}, },
} };
const useRequest = (initOptions) => { const useRequest = (initOptions) => {
const _options = Object.assign({}, defaultOptions, initOptions); const _options = Object.assign({}, defaultOptions, initOptions);
return async (url = '', method = 'get', options) => { return async (url = "", method = "get", options) => {
const mergedOptions = Object.assign({}, _options, options); const mergedOptions = Object.assign({}, _options, options);
try { try {
const response = await axios({ const response = await axios({
url, url,
method, method,
data: method === 'get' ? null : mergedOptions.data, data: method === "get" ? null : mergedOptions.data,
withCredentials: true, withCredentials: true,
...mergedOptions.requestOptions ...mergedOptions.requestOptions,
}); });
successRequest(mergedOptions.notification.show && mergedOptions.notification.success, 'request_data'); successRequest(mergedOptions.notification.show && mergedOptions.notification.success, "request_data");
return response; return response;
} catch (error) { } catch (error) {
if (error.response) { if (error.response) {
errorResponse(error.response, mergedOptions.notification.show && mergedOptions.notification.failed, 'request_data'); errorResponse(
error.response,
mergedOptions.notification.show && mergedOptions.notification.failed,
"request_data"
);
} }
throw error; throw error;
} }
} };
} };
export default useRequest export default useRequest;

View File

@@ -1,10 +1,9 @@
import {useContext} from "react"; import { useContext } from "react";
import {TableSettingContext} from "../contexts/tableSetting"; import { TableSettingContext } from "../contexts/tableSetting";
const useTableSetting = () => { const useTableSetting = () => {
const {settingStore, hideAction, sortAction, filterAction, refactorAction} = const { settingStore, hideAction, sortAction, filterAction, refactorAction } = useContext(TableSettingContext);
useContext(TableSettingContext); return { settingStore, hideAction, sortAction, filterAction, refactorAction };
return {settingStore, hideAction, sortAction, filterAction, refactorAction};
}; };
export default useTableSetting; export default useTableSetting;