PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / trunk
Search Atlas SEO – OTTO AI SEO Automation for WordPress vtrunk
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | views/metasync-redirection.php +282 -414 2.6.3 → trunk View file →
@@ -26,15 +26,34 @@
26 26 .column-cb {
27 27 width: 2.2em;
28 28 }
29 29
30 + /* NOTE: render_tab_content() in includes/class-metasync-redirections-admin.php always
31 + renders both the Redirections and 404 Monitor tab markup into the page (JS just
32 + toggles which one is visible), so this view's <style> block and
33 + views/metasync-404-monitor.php's both land in the DOM together. Keep their
34 + .check-column rules identical, or whichever one is later in source order silently
35 + wins the cascade and undoes the other's fix. */
30 36 .wrap .wp-list-table th.check-column,
31 37 .wrap .wp-list-table td.check-column {
32 38 width: 2.2em;
33 - padding: 8px 0 0 3px;
39 + }
40 +
41 + /* Header/footer checkbox cell only ever holds a single-line label, so centring it works. */
42 + .wrap .wp-list-table td.check-column {
43 + padding: 0 0 0 3px;
34 44 vertical-align: middle;
35 45 }
36 46
47 + /* Row checkbox cells sit next to columns that can wrap onto multiple lines (e.g. "From"
48 + plus its pattern-type badge). Centring against the whole (taller) row pushes the
49 + checkbox below the first line of text, so align it to the top like the other columns
50 + and nudge it down just enough to sit level with that first line instead. */
51 + .wrap .wp-list-table th.check-column {
52 + padding: 9px 0 0 3px;
53 + vertical-align: top;
54 + }
55 +
37 56 .wrap .wp-list-table th.check-column input[type="checkbox"],
38 57 .wrap .wp-list-table td.check-column input[type="checkbox"] {
39 58 margin: 0;
40 59 padding: 0;
@@ -40,8 +59,16 @@
40 59 padding: 0;
41 60 vertical-align: middle;
42 61 }
43 62
63 + /* The header/footer cell's row height is computed from the sortable column links'
64 + padding and rounds ~1px taller than the checkbox's own box, so vertical-align:
65 + middle alone still lands it a hair below the column label text. Nudge it up to
66 + sit pixel-level centred (measured against "From" in a real browser). */
67 + .wrap .wp-list-table td.check-column input[type="checkbox"] {
68 + transform: translateY(-1px);
69 + }
70 +
44 71 .column-sources_from {
45 72 width: 25%;
46 73 }
47 74
@@ -193,10 +220,10 @@
193 220 }
194 221
195 222 /* Specific button targeting */
196 223 .wrap input[type="submit"]#doaction,
197 - .wrap input[type="submit"]#post-query-submit,
198 - .wrap input[type="submit"]#search-submit,
224 + .wrap input[type="submit"]#redirections-filter-submit,
225 + .wrap input[type="submit"]#redirections-search-submit,
199 226 .wrap input[type="submit"].button {
200 227 background: var(--dashboard-accent) !important;
201 228 border-color: var(--dashboard-accent) !important;
202 229 color: white !important;
@@ -205,10 +232,10 @@
205 232 transition: all 0.3s ease !important;
206 233 }
207 234
208 235 .wrap input[type="submit"]#doaction:hover,
209 - .wrap input[type="submit"]#post-query-submit:hover,
210 - .wrap input[type="submit"]#search-submit:hover,
236 + .wrap input[type="submit"]#redirections-filter-submit:hover,
237 + .wrap input[type="submit"]#redirections-search-submit:hover,
211 238 .wrap input[type="submit"].button:hover {
212 239 background: var(--dashboard-accent-hover) !important;
213 240 border-color: var(--dashboard-accent-hover) !important;
214 241 transform: translateY(-1px) !important;
@@ -239,10 +266,11 @@
239 266 color: white !important;
240 267 text-decoration: none !important;
241 268 }
242 269
243 - /* Add Redirection Form Styling */
270 + /* Add Redirection Form Styling — hidden by default, shown via inline style by JS */
244 271 .wrap #add-redirection-form {
272 + display: none;
245 273 background: var(--dashboard-card-bg) !important;
246 274 border: 1px solid var(--dashboard-border) !important;
247 275 border-radius: 12px !important;
248 276 padding: 24px !important;
@@ -533,323 +561,186 @@
533 561 color: var(--dashboard-text-primary) !important;
534 562 }
535 563
536 564 /* Tablenav styling */
565 + /* ── Tablenav ── */
537 566 .wrap .tablenav {
538 567 background: var(--dashboard-card-bg);
539 568 border: 1px solid var(--dashboard-border);
540 569 border-radius: 8px;
541 - padding: 18px 24px;
570 + padding: 12px 16px;
542 571 margin-bottom: 16px;
543 572 box-shadow: var(--dashboard-shadow);
544 - display: flex !important;
545 - align-items: center !important;
546 - justify-content: space-between !important;
547 - flex-wrap: nowrap !important;
548 - gap: 18px !important;
549 - min-height: 64px !important;
550 - overflow-x: auto !important;
551 - overflow-y: hidden !important;
573 + display: flex;
574 + align-items: center;
575 + flex-wrap: wrap;
576 + gap: 8px;
552 577 }
578 + .wrap .tablenav * { box-sizing: border-box; margin: 0; }
553 579
580 + /* Left group: filters / bulk actions — shrinks equally with search */
581 + .wrap .tablenav .alignleft,
554 582 .wrap .tablenav .actions {
555 - display: flex !important;
556 - align-items: center !important;
557 - gap: 12px !important;
558 - flex-wrap: nowrap !important;
559 - flex-shrink: 0 !important;
560 - min-width: 0 !important;
583 + display: flex;
584 + align-items: center;
585 + flex-wrap: nowrap;
586 + gap: 6px;
587 + flex: 1 1 0;
588 + min-width: 0;
561 589 }
562 590
563 - .wrap .tablenav .alignleft {
564 - display: flex !important;
565 - align-items: center !important;
566 - gap: 12px !important;
567 - flex-wrap: nowrap !important;
568 - flex-shrink: 0 !important;
569 - min-width: 0 !important;
591 + /* Right group: pagination */
592 + .wrap .tablenav .alignright {
593 + display: flex;
594 + align-items: center;
595 + flex-wrap: wrap;
596 + gap: 6px;
597 + margin-left: auto;
598 + min-width: 0;
570 599 }
571 600
572 - .wrap .tablenav .alignright {
573 - display: flex !important;
574 - align-items: center !important;
575 - gap: 12px !important;
576 - margin-left: auto !important;
577 - flex-shrink: 0 !important;
578 - min-width: 0 !important;
601 + /* Search box — sits inline with filters, shrinks to fit */
602 + .wrap .tablenav .metasync-search-box {
603 + display: flex;
604 + align-items: center;
605 + flex-wrap: nowrap;
606 + gap: 6px;
607 + flex: 1 1 0;
608 + min-width: 0;
579 609 }
610 + .wrap .tablenav .metasync-search-box input[type="search"] {
611 + flex: 1 1 60px;
612 + min-width: 0;
613 + width: auto;
614 + }
580 615
616 + /* ── Shared control height ── */
617 + .wrap .tablenav select,
618 + .wrap .tablenav input[type="search"],
619 + .wrap .tablenav input[type="text"],
620 + .wrap .tablenav input[type="submit"],
621 + .wrap .tablenav input[type="button"],
622 + .wrap .tablenav .button {
623 + height: 34px;
624 + font-size: 13px;
625 + font-weight: 500;
626 + border-radius: 6px;
627 + padding: 0 10px;
628 + line-height: 34px;
629 + }
630 +
631 + /* Selects — shrinkable, text truncates when compressed */
581 632 .wrap .tablenav select {
582 - background: var(--dashboard-card-bg) !important;
583 - border: 1px solid var(--dashboard-border) !important;
584 - color: var(--dashboard-text-primary) !important;
585 - border-radius: 6px !important;
586 - padding: 10px 16px !important;
587 - height: 40px !important;
588 - vertical-align: middle !important;
589 - text-align: left !important;
590 - line-height: 1.4 !important;
591 - font-size: 13px !important;
592 - font-weight: 500 !important;
593 - appearance: none !important;
594 - -moz-appearance: none !important;
595 - -webkit-appearance: none !important;
596 - background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e") !important;
597 - background-repeat: no-repeat !important;
598 - background-position: right 12px center !important;
599 - background-size: 16px !important;
600 - padding-right: 40px !important;
601 - cursor: pointer !important;
602 - width: 140px !important;
603 - flex-shrink: 0 !important;
604 - white-space: nowrap !important;
605 - overflow: hidden !important;
606 - text-overflow: ellipsis !important;
633 + background: var(--dashboard-card-bg);
634 + border: 1px solid var(--dashboard-border);
635 + color: var(--dashboard-text-primary);
636 + appearance: none;
637 + -webkit-appearance: none;
638 + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
639 + background-repeat: no-repeat;
640 + background-position: right 6px center;
641 + background-size: 14px;
642 + padding-right: 28px;
643 + cursor: pointer;
644 + flex: 1 1 0;
645 + min-width: 0;
646 + overflow: hidden;
647 + text-overflow: ellipsis;
607 648 }
608 -
609 649 .wrap .tablenav select:focus {
610 - border-color: var(--dashboard-accent) !important;
611 - box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
612 - outline: none !important;
650 + border-color: var(--dashboard-accent);
651 + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
652 + outline: none;
613 653 }
614 -
615 654 .wrap .tablenav select option {
616 - background: var(--dashboard-card-bg) !important;
617 - color: var(--dashboard-text-primary) !important;
618 - padding: 8px !important;
619 - font-size: 13px !important;
620 - font-weight: 500 !important;
655 + background: var(--dashboard-card-bg);
656 + color: var(--dashboard-text-primary);
621 657 }
622 658
659 + /* Text / search inputs — fully flexible */
623 660 .wrap .tablenav input[type="search"],
624 661 .wrap .tablenav input[type="text"] {
625 - background: var(--dashboard-card-bg) !important;
626 - border: 1px solid var(--dashboard-border) !important;
627 - color: var(--dashboard-text-primary) !important;
628 - border-radius: 6px !important;
629 - padding: 10px 16px !important;
630 - height: 40px !important;
631 - vertical-align: middle !important;
632 - width: 250px !important;
633 - flex-shrink: 0 !important;
634 - white-space: nowrap !important;
635 - overflow: hidden !important;
636 - text-overflow: ellipsis !important;
662 + background: var(--dashboard-card-bg);
663 + border: 1px solid var(--dashboard-border);
664 + color: var(--dashboard-text-primary);
665 + width: auto;
666 + min-width: 0;
667 + flex: 1 1 80px;
637 668 }
638 -
639 - .wrap .tablenav input[type="submit"] {
640 - height: 40px !important;
641 - vertical-align: middle !important;
642 - line-height: 1 !important;
643 - padding: 10px 20px !important;
644 - flex-shrink: 0 !important;
645 - white-space: nowrap !important;
646 - width: auto !important;
647 - min-width: 100px !important;
669 + .wrap .tablenav input[type="search"]:focus,
670 + .wrap .tablenav input[type="text"]:focus {
671 + border-color: var(--dashboard-accent);
672 + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
673 + outline: none;
648 674 }
649 675
650 - .wrap .tablenav .search-box {
651 - margin: 0 !important;
652 - display: flex !important;
653 - align-items: center !important;
654 - gap: 12px !important;
655 - height: 40px !important;
656 - padding: 0 !important;
657 - border: none !important;
658 - background: transparent !important;
659 - flex-shrink: 0 !important;
660 - white-space: nowrap !important;
661 - min-width: 0 !important;
676 + /* Pagination current-page — narrow */
677 + .wrap .tablenav-pages input.current-page,
678 + .wrap .tablenav .current-page {
679 + width: 3em !important;
680 + min-width: 3em !important;
681 + flex: 0 0 3em !important;
682 + text-align: center;
683 + padding: 0 4px;
662 684 }
663 685
664 - .wrap .tablenav .search-box input[type="search"] {
665 - margin: 0 !important;
666 - height: 32px !important;
667 - vertical-align: middle !important;
668 - line-height: 1 !important;
669 - box-sizing: border-box !important;
670 - padding: 8px 12px !important;
671 - border: 1px solid var(--dashboard-border) !important;
672 - background: var(--dashboard-card-bg) !important;
673 - color: var(--dashboard-text-primary) !important;
674 - border-radius: 6px !important;
675 - font-size: 13px !important;
686 + /* Buttons */
687 + .wrap .tablenav input[type="submit"],
688 + .wrap .tablenav input[type="button"],
689 + .wrap .tablenav .button {
690 + white-space: nowrap;
691 + display: inline-flex;
692 + align-items: center;
693 + justify-content: center;
694 + flex-shrink: 0;
676 695 }
677 696
678 - /* Specific search button alignment */
679 - .wrap .tablenav .search-box input[type="submit"] {
680 - height: 32px !important;
681 - vertical-align: middle !important;
682 - line-height: 1 !important;
683 - padding: 8px 12px !important;
684 - box-sizing: border-box !important;
685 - margin: 0 !important;
686 - border-radius: 6px !important;
687 - font-size: 13px !important;
688 - }
689 697
690 - /* Additional targeting for WordPress default styles */
691 - .wrap .tablenav p.search-box {
692 - display: flex !important;
693 - align-items: center !important;
694 - gap: 8px !important;
695 - height: 32px !important;
696 - margin: 0 !important;
697 - padding: 0 !important;
698 - line-height: 1 !important;
699 - }
700 -
701 - .wrap .tablenav p.search-box input {
702 - margin: 0 !important;
703 - vertical-align: middle !important;
704 - line-height: 1 !important;
705 - }
706 -
707 - /* Specific ID targeting for search elements - fixed padding */
708 - .wrap .tablenav #post-search-input {
709 - height: 32px !important;
710 - line-height: 1 !important;
711 - vertical-align: middle !important;
712 - margin-left: 15px !important;
713 - padding: 8px 12px !important;
714 - border: 1px solid var(--dashboard-border) !important;
715 - background: var(--dashboard-card-bg) !important;
716 - color: var(--dashboard-text-primary) !important;
717 - border-radius: 6px !important;
718 - font-size: 13px !important;
719 - box-sizing: border-box !important;
720 - }
721 -
722 - .wrap .tablenav #search-submit {
723 - height: 32px !important;
724 - line-height: 1 !important;
725 - vertical-align: middle !important;
726 - margin: 0 !important;
727 - padding: 8px 12px !important;
728 - border-radius: 6px !important;
729 - font-size: 13px !important;
730 - box-sizing: border-box !important;
731 - display: inline-block !important;
732 - }
733 -
734 - /* Force alignment with transform if needed */
735 - .wrap .tablenav .search-box {
736 - transform: translateY(0) !important;
737 - }
738 -
739 - .wrap .tablenav .search-box input {
740 - transform: translateY(0) !important;
741 - }
742 -
743 - /* Item count styling - fixed alignment */
698 + /* Item count badge */
744 699 .wrap .tablenav .displaying-num {
745 - color: var(--dashboard-text-primary) !important;
746 - font-size: 13px !important;
747 - font-weight: 500 !important;
748 - background: var(--dashboard-card-hover) !important;
749 - padding: 6px 12px !important;
750 - border-radius: 6px !important;
751 - border: 1px solid var(--dashboard-border) !important;
752 - margin: 0 !important;
753 - display: inline-block !important;
754 - vertical-align: middle !important;
755 - line-height: 1 !important;
756 - height: 32px !important;
757 - box-sizing: border-box !important;
700 + color: var(--dashboard-text-primary);
701 + font-size: 12px;
702 + font-weight: 500;
703 + background: var(--dashboard-card-hover);
704 + padding: 0 10px;
705 + border-radius: 6px;
706 + border: 1px solid var(--dashboard-border);
707 + height: 30px;
708 + line-height: 28px;
709 + white-space: nowrap;
758 710 }
759 711
760 - /* Alternative item count selectors - maintain inline flow */
761 - .wrap .tablenav .alignright {
762 - display: flex !important;
763 - align-items: center !important;
764 - gap: 12px !important;
765 - margin-left: auto !important;
766 - }
767 -
768 - /* WordPress pagination controls - ensure right alignment */
712 + /* Pagination controls */
769 713 .wrap .tablenav-pages {
770 - display: flex !important;
771 - align-items: center !important;
772 - gap: 8px !important;
773 - margin-left: auto !important;
774 - justify-content: flex-end !important;
714 + display: flex;
715 + align-items: center;
716 + gap: 4px;
717 + margin-left: auto;
718 + flex-wrap: wrap;
775 719 }
776 -
777 -
778 - .wrap .tablenav-pages .displaying-num {
779 - color: var(--dashboard-text-primary) !important;
780 - font-size: 13px !important;
781 - font-weight: 500 !important;
782 - background: var(--dashboard-card-hover) !important;
783 - padding: 6px 12px !important;
784 - border-radius: 6px !important;
785 - border: 1px solid var(--dashboard-border) !important;
786 - margin-right: 12px !important;
787 - white-space: nowrap !important;
720 + .wrap .tablenav-pages .paging-input {
721 + display: inline-flex;
722 + align-items: center;
723 + gap: 4px;
788 724 }
789 -
790 - .wrap .tablenav .alignright p,
791 - .wrap .tablenav .alignright span {
792 - color: var(--dashboard-text-primary) !important;
793 - font-size: 13px !important;
794 - font-weight: 500 !important;
795 - margin: 0 !important;
796 - background: var(--dashboard-card-hover) !important;
797 - padding: 0 !important;
798 - border-radius: 6px !important;
799 - border: 1px solid var(--dashboard-border) !important;
800 - display: inline-block !important;
801 - vertical-align: middle !important;
802 - line-height: 1 !important;
803 - height: 32px !important;
804 - box-sizing: border-box !important;
725 + .wrap .tablenav .alignright span,
726 + .wrap .tablenav .alignright p {
727 + color: var(--dashboard-text-primary);
728 + font-size: 12px;
729 + padding: 0;
730 + border: none;
731 + background: transparent;
732 + height: auto;
805 733 }
806 734
807 - /* Ensure all buttons in tablenav are properly aligned */
808 - .wrap .tablenav .button,
809 - .wrap .tablenav input[type="submit"],
810 - .wrap .tablenav input[type="button"] {
811 - vertical-align: middle !important;
812 - height: 32px !important;
813 - line-height: 1 !important;
814 - display: inline-flex !important;
815 - align-items: center !important;
816 - justify-content: center !important;
817 - text-align: center !important;
818 - font-size: 13px !important;
819 - font-weight: 500 !important;
735 + .wrap .tablenav label {
736 + padding: 0;
737 + white-space: nowrap;
738 + font-weight: 500;
739 + color: var(--dashboard-text-primary);
740 + font-size: 13px;
820 741 }
821 742
822 - /* Specific fix for Apply button text alignment */
823 - .wrap .tablenav input[type="submit"][value="Apply"] {
824 - text-align: center !important;
825 - vertical-align: middle !important;
826 - line-height: 1 !important;
827 - padding: 6px 12px !important;
828 - display: inline-flex !important;
829 - align-items: center !important;
830 - justify-content: center !important;
831 - }
832 -
833 - /* Fix for number input fields */
834 - .wrap .tablenav input[type="number"] {
835 - background: var(--dashboard-card-bg) !important;
836 - border: 1px solid var(--dashboard-border) !important;
837 - color: var(--dashboard-text-primary) !important;
838 - border-radius: 6px !important;
839 - padding: 6px 12px !important;
840 - height: 32px !important;
841 - vertical-align: middle !important;
842 - width: auto !important;
843 - min-width: 80px !important;
844 - }
845 -
846 - .wrap .tablenav input[type="number"]:focus {
847 - border-color: var(--dashboard-accent) !important;
848 - box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
849 - outline: none !important;
850 - }
851 -
852 743 /* Page title action styling */
853 744 .page-title-action {
854 745 background: var(--dashboard-accent) !important;
855 746 border-color: var(--dashboard-accent) !important;
@@ -862,9 +753,8 @@
862 753 display: inline-flex !important;
863 754 align-items: center !important;
864 755 gap: 8px !important;
865 756 }
866 -
867 757 .page-title-action:hover {
868 758 background: var(--dashboard-accent-hover) !important;
869 759 border-color: var(--dashboard-accent-hover) !important;
870 760 transform: translateY(-1px);
@@ -872,144 +762,42 @@
872 762 color: white !important;
873 763 }
874 764
875 765 /* Status indicators */
876 - .status-active {
877 - color: var(--dashboard-success) !important;
878 - font-weight: 600;
879 - }
766 + .status-active { color: var(--dashboard-success) !important; font-weight: 600; }
767 + .status-inactive { color: var(--dashboard-text-secondary) !important; font-weight: 600; }
880 768
881 - .status-inactive {
882 - color: var(--dashboard-text-secondary) !important;
883 - font-weight: 600;
884 - }
885 -
886 769 /* HTTP code styling */
887 - .http-code-301, .http-code-302, .http-code-307 {
888 - color: var(--dashboard-accent) !important;
889 - font-weight: 600;
890 - }
770 + .http-code-301, .http-code-302, .http-code-307 { color: var(--dashboard-accent) !important; font-weight: 600; }
771 + .http-code-410, .http-code-451 { color: var(--dashboard-warning) !important; font-weight: 600; }
891 772
892 - .http-code-410, .http-code-451 {
893 - color: var(--dashboard-warning) !important;
894 - font-weight: 600;
895 - }
773 + /* Duplicate element guards */
774 + .wrap .wp-list-table + .wp-list-table { display: none !important; }
775 + .wrap .tablenav + .tablenav { display: none !important; }
776 + .wrap .wp-list-table thead:not(:first-of-type) { display: none !important; }
777 + .wrap .wp-list-table tfoot { display: none !important; }
896 778
897 - /* Fix for duplicate table elements */
898 - .wrap .wp-list-table + .wp-list-table {
899 - display: none !important;
900 - }
901 -
902 - /* Hide duplicate bulk actions */
903 - .wrap .tablenav + .tablenav {
904 - display: none !important;
905 - }
906 -
907 - /* Ensure only one table header is visible */
908 - .wrap .wp-list-table thead:not(:first-of-type) {
909 - display: none !important;
910 - }
911 -
912 - /* Force no line breaks - aggressive approach */
913 - .wrap .tablenav * {
914 - box-sizing: border-box !important;
915 - }
916 -
917 - .wrap .tablenav .alignleft > *,
918 - .wrap .tablenav .alignright > *,
919 - .wrap .tablenav .actions > * {
920 - display: inline-block !important;
921 - vertical-align: middle !important;
922 - margin: 0 !important;
923 - }
924 -
925 - /* Specific element spacing */
926 - .wrap .tablenav label {
927 - margin-right: 12px !important;
928 - margin-left: 4px !important;
929 - padding: 8px 4px !important;
930 - white-space: nowrap !important;
931 - flex-shrink: 0 !important;
932 - font-weight: 500 !important;
933 - color: var(--dashboard-text-primary) !important;
934 - display: inline-block !important;
935 - vertical-align: middle !important;
936 - }
937 -
938 - /* Responsive behavior for smaller screens */
939 - @media (max-width: 1400px) {
940 - .wrap .tablenav {
941 - overflow-x: auto !important;
942 - overflow-y: hidden !important;
943 - padding: 16px 20px !important;
944 - }
945 -
946 - .wrap .tablenav select {
947 - width: 120px !important;
948 - padding: 8px 12px !important;
949 - height: 36px !important;
950 - }
951 -
952 - .wrap .tablenav input[type="search"],
953 - .wrap .tablenav input[type="text"] {
954 - width: 200px !important;
955 - padding: 8px 12px !important;
956 - height: 36px !important;
957 - }
958 -
959 - .wrap .tablenav input[type="submit"] {
960 - padding: 8px 16px !important;
961 - height: 36px !important;
962 - }
963 - }
964 -
779 + /* ── Responsive ── */
965 780 @media (max-width: 1200px) {
966 - .wrap .tablenav {
967 - overflow-x: auto !important;
968 - overflow-y: hidden !important;
969 - padding: 14px 18px !important;
970 - }
971 -
972 - .wrap .tablenav select {
973 - width: 100px !important;
974 - padding: 6px 10px !important;
975 - height: 32px !important;
976 - }
977 -
781 + .wrap .tablenav { padding: 10px 12px; gap: 6px; }
782 + .wrap .tablenav select,
978 783 .wrap .tablenav input[type="search"],
979 - .wrap .tablenav input[type="text"] {
980 - width: 180px !important;
981 - padding: 6px 10px !important;
982 - height: 32px !important;
784 + .wrap .tablenav input[type="text"],
785 + .wrap .tablenav input[type="submit"],
786 + .wrap .tablenav .button {
787 + height: 30px; font-size: 12px; line-height: 30px; padding: 0 8px;
983 788 }
984 -
985 - .wrap .tablenav input[type="submit"] {
986 - padding: 6px 12px !important;
987 - height: 32px !important;
988 - }
789 + .wrap .tablenav select { padding-right: 22px; background-size: 12px; }
989 790 }
990 791
991 - @media (max-width: 768px) {
992 - .wrap .tablenav {
993 - flex-direction: column !important;
994 - align-items: stretch !important;
995 - gap: 12px !important;
996 - }
997 -
792 + @media (max-width: 782px) {
793 + .wrap .tablenav { padding: 10px; gap: 8px; }
998 794 .wrap .tablenav .alignleft,
999 - .wrap .tablenav .alignright {
1000 - justify-content: center !important;
1001 - margin: 0 !important;
1002 - }
1003 -
1004 - .wrap .tablenav select,
1005 - .wrap .tablenav input[type="search"],
1006 - .wrap .tablenav input[type="text"],
1007 - .wrap .tablenav input[type="submit"] {
1008 - width: 100% !important;
1009 - max-width: none !important;
1010 - min-width: auto !important;
1011 - }
795 + .wrap .tablenav .alignright,
796 + .wrap .tablenav .actions,
797 + .wrap .tablenav .metasync-search-box { width: 100%; flex: 1 1 100%; }
798 + .wrap .tablenav select { flex: 1 1 0%; }
799 + .wrap .tablenav-pages { margin-left: 0; width: 100%; justify-content: center; }
1012 800 }
1013 801
1014 802 /* Description text styling */
1015 803 .wrap .description,
@@ -1017,8 +805,32 @@
1017 805 color: var(--dashboard-text-secondary, #9ca3af) !important;
1018 806 font-size: 13px !important;
1019 807 line-height: 1.5 !important;
1020 808 }
809 +
810 + /* Health status column */
811 + .column-health_status { width: 7%; text-align: center; }
812 + .health-status-cell { display: inline-block; cursor: default; font-size: 16px; }
813 +
814 + /* Body-appended floating tooltip — escapes all table stacking contexts */
815 + .health-tooltip-floating {
816 + position: fixed;
817 + display: block;
818 + background: #1e293b;
819 + border: 1px solid #475569;
820 + border-radius: 6px;
821 + padding: 6px 12px;
822 + z-index: 999999;
823 + white-space: nowrap;
824 + font-size: 12px;
825 + color: #cbd5e1;
826 + box-shadow: 0 4px 16px rgba(0,0,0,0.6);
827 + pointer-events: none;
828 + }
829 + .wrap .wp-list-table thead tr:first-child th:first-child { border-top-left-radius: 12px; }
830 + .wrap .wp-list-table thead tr:first-child th:last-child { border-top-right-radius: 12px; }
831 + .wrap .wp-list-table tbody tr:last-child td:first-child { border-bottom-left-radius: 12px; }
832 + .wrap .wp-list-table tbody tr:last-child td:last-child { border-bottom-right-radius: 12px; }
1021 833 </style>
1022 834
1023 835 <div class="wrap">
1024 836 <a href="<?php echo esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-redirections&action=add')); ?>" class="page-title-action">Add New Redirect</a>
@@ -1026,13 +838,71 @@
1026 838 <!-- Import from SEO Plugins Button -->
1027 839 <a href="<?php echo esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-import-external&tab=redirections')); ?>" class="page-title-action" style="background: #10b981 !important; border-color: #10b981 !important;">
1028 840 <span>📥</span> Import from SEO Plugins
1029 841 </a>
842 +
843 + <!-- Check Health Button -->
844 + <button type="button" id="metasync-check-health-btn" class="page-title-action" style="background: #f59e0b !important; border-color: #f59e0b !important; color: #000 !important;">
845 + Check Health
846 + </button>
847 +
848 + <!-- Allow External Redirects Setting -->
849 + <?php
850 + if (isset($_POST['metasync_save_external_redirects']) && current_user_can('manage_options') && wp_verify_nonce($_POST['_metasync_external_nonce'], 'metasync_external_redirects_toggle')) {
851 + $allow_external = isset($_POST['metasync_allow_external_redirects']) ? 1 : 0;
852 + update_option('metasync_allow_external_redirects', $allow_external, true);
853 + echo '<div class="notice notice-success is-dismissible"><p>External redirects setting updated.</p></div>';
854 + }
855 + $allow_external_current = get_option('metasync_allow_external_redirects', 0);
856 + ?>
857 + <div style="background: var(--dashboard-card-bg, #1a1f26); border: 1px solid var(--dashboard-border, #374151); border-radius: 8px; padding: 12px 16px; margin: 15px 0; display: flex; align-items: center; gap: 12px;">
858 + <form method="post" style="display: flex; align-items: center; gap: 12px; margin: 0;">
859 + <?php wp_nonce_field('metasync_external_redirects_toggle', '_metasync_external_nonce'); ?>
860 + <label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--dashboard-text-primary, #fff); font-weight: 500;">
861 + <input type="checkbox" name="metasync_allow_external_redirects" value="1" <?php checked($allow_external_current, 1); ?> onchange="this.form.submit();" style="width: 16px; height: 16px; margin: 0; flex-shrink: 0;">
862 + Allow External Redirects
863 + </label>
864 + <input type="hidden" name="metasync_save_external_redirects" value="1">
865 + <?php if ($allow_external_current) : ?>
866 + <span style="color: var(--dashboard-warning, #f59e0b); font-size: 13px;">External redirects are enabled. Redirects can point to other websites.</span>
867 + <?php else : ?>
868 + <span style="color: var(--dashboard-text-secondary, #9ca3af); font-size: 13px;">External redirects are disabled. All redirects will stay on your site for security.</span>
869 + <?php endif; ?>
870 + </form>
871 + </div>
872 +
873 +
874 + <!-- Auto-Redirect on Slug Change Setting -->
875 + <?php
876 + if (isset($_POST['metasync_save_auto_redirect']) && current_user_can('manage_options') && wp_verify_nonce($_POST['_metasync_auto_redirect_nonce'], 'metasync_auto_redirect_toggle')) {
877 + $auto_redirect = isset($_POST['metasync_auto_redirect_enabled']) ? 1 : 0;
878 + update_option('metasync_auto_redirect_enabled', $auto_redirect, true);
879 + echo '<div class="notice notice-success is-dismissible"><p>Auto-redirect setting updated.</p></div>';
880 + }
881 + $auto_redirect_current = get_option('metasync_auto_redirect_enabled', 1);
882 + ?>
883 + <div style="background: var(--dashboard-card-bg, #1a1f26); border: 1px solid var(--dashboard-border, #374151); border-radius: 8px; padding: 12px 16px; margin: 15px 0; display: flex; align-items: center; gap: 12px;">
884 + <form method="post" style="display: flex; align-items: center; gap: 12px; margin: 0;">
885 + <?php wp_nonce_field('metasync_auto_redirect_toggle', '_metasync_auto_redirect_nonce'); ?>
886 + <label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--dashboard-text-primary, #fff); font-weight: 500;">
887 + <input type="checkbox" name="metasync_auto_redirect_enabled" value="1" <?php checked($auto_redirect_current, 1); ?> onchange="this.form.submit();" style="width: 16px; height: 16px; margin: 0; flex-shrink: 0;">
888 + Auto-Redirect on Slug Change
889 + </label>
890 + <input type="hidden" name="metasync_save_auto_redirect" value="1">
891 + <?php if ($auto_redirect_current) : ?>
892 + <span style="color: var(--dashboard-text-secondary, #9ca3af); font-size: 13px;">Redirects are created automatically when a post or page slug changes.</span>
893 + <?php else : ?>
894 + <span style="color: var(--dashboard-warning, #f59e0b); font-size: 13px;">Auto-redirects are paused. Slug changes will not create redirect rules (useful during migrations or bulk edits).</span>
895 + <?php endif; ?>
896 + </form>
897 + </div>
898 +
1030 899 <!-- Forms are NOT created automatically, so you need to wrap the table in one to use features like bulk actions -->
1031 900 <form id="redirection-form" method="post" action="">
1032 901 <?php wp_nonce_field('metasync_redirection_form', 'metasync_redirection_nonce'); ?>
1033 902 <?php include "metasync-add-redirection.php";
1034 - $request_data = metasync_sanitize_input_array($_REQUEST); ?>
903 + $request_data = metasync_sanitize_input_array($_REQUEST);
904 + $list_state = Metasync_Per_Page_Helper::request_state('redirections'); ?>
1035 905 <!-- For plugins, we also need to ensure that the form posts back to our current page -->
1036 906 <input type="hidden" name="page" value="<?php echo esc_attr($request_data['page']) ?>" />
1037 907
1038 908 <!-- Search and Filter Controls -->
@@ -1065,17 +935,15 @@
1065 935 <option value="410" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '410'); ?>>410 Gone</option>
1066 936 <option value="451" <?php selected(isset($_REQUEST['http_code_filter']) ? $_REQUEST['http_code_filter'] : '', '451'); ?>>451 Unavailable</option>
1067 937 </select>
1068 938
1069 - <input type="submit" name="filter_action" id="post-query-submit" class="button" value="Filter">
939 + <input type="submit" name="filter_action" id="redirections-filter-submit" class="button" value="Filter">
1070 940 </div>
1071 941
1072 - <div class="alignright">
1073 - <p class="search-box">
1074 - <label class="screen-reader-text" for="post-search-input">Search Redirections:</label>
1075 - <input type="search" id="post-search-input" name="s" value="<?php echo esc_attr(isset($_REQUEST['s']) ? $_REQUEST['s'] : ''); ?>" placeholder="Search redirections...">
1076 - <input type="submit" id="search-submit" class="button" value="Search">
1077 - </p>
942 + <div class="metasync-search-box">
943 + <label class="screen-reader-text" for="redirections-search-input">Search Redirections:</label>
944 + <input type="search" id="redirections-search-input" name="s_redir" value="<?php echo esc_attr($list_state['s_redir'] ?? ''); ?>" placeholder="Search redirections...">
945 + <input type="submit" name="search_submit" id="redirections-search-submit" class="button" value="Search">
1078 946 </div>
1079 947 </div>
1080 948
1081 949 <!-- Now we can render the completed list table -->