';
echo '
';
if ( ! empty( $this->charts ) ) {
- echo '
';
- $count = 0;
- foreach ( $this->charts as $placeholder_id => $chart ) {
- // show the sidebar after the first 3 charts.
- ++$count;
- $enable_controls = false;
- $settings = isset( $chart['settings'] ) ? $chart['settings'] : array();
- if ( ! empty( $settings['controls']['controlType'] ) ) {
- $column_index = $settings['controls']['filterColumnIndex'];
- $column_label = $settings['controls']['filterColumnLabel'];
- if ( 'false' !== $column_index || 'false' !== $column_label ) {
- $enable_controls = true;
+ if ( $this->_isListView() ) {
+ echo '
';
+ $this->_renderSidebar();
+ echo '
';
+ echo '';
+ echo '| ' . esc_html__( 'ID', 'visualizer' ) . ' | ';
+ echo '' . esc_html__( 'Title', 'visualizer' ) . ' | ';
+ echo '' . esc_html__( 'Type', 'visualizer' ) . ' | ';
+ echo '' . esc_html__( 'Shortcode', 'visualizer' ) . ' | ';
+ echo '' . esc_html__( 'Actions', 'visualizer' ) . ' | ';
+ echo '
';
+ foreach ( $this->charts as $placeholder_id => $chart ) {
+ $enable_controls = false;
+ $settings = isset( $chart['settings'] ) ? $chart['settings'] : array();
+ if ( ! empty( $settings['controls']['controlType'] ) ) {
+ $column_index = $settings['controls']['filterColumnIndex'];
+ $column_label = $settings['controls']['filterColumnLabel'];
+ if ( 'false' !== $column_index || 'false' !== $column_label ) {
+ $enable_controls = true;
+ }
}
- }
- if ( 3 === $count ) {
- $this->_renderSidebar();
- $this->_renderChartBox( $placeholder_id, $chart['id'], $enable_controls );
- } else {
$this->_renderChartBox( $placeholder_id, $chart['id'], $enable_controls );
}
- }
- // show the sidebar if there are less than 3 charts.
- if ( $count < 3 ) {
+ echo '
';
+ echo '
';
+ } else {
+ echo '
';
$this->_renderSidebar();
+ foreach ( $this->charts as $placeholder_id => $chart ) {
+ $enable_controls = false;
+ $settings = isset( $chart['settings'] ) ? $chart['settings'] : array();
+ if ( ! empty( $settings['controls']['controlType'] ) ) {
+ $column_index = $settings['controls']['filterColumnIndex'];
+ $column_label = $settings['controls']['filterColumnLabel'];
+ if ( 'false' !== $column_index || 'false' !== $column_label ) {
+ $enable_controls = true;
+ }
+ }
+ $this->_renderChartBox( $placeholder_id, $chart['id'], $enable_controls );
+ }
+ echo '
';
}
- echo '
';
} else {
- echo '
';
+ echo '
';
echo '
';
echo '
';
echo '
', esc_html__( 'No charts found', 'visualizer' ), '
';
@@ -321,7 +346,7 @@ private function _renderLibrary() {
echo '
';
echo '
';
echo '
';
- echo '
';
+ echo '
';
echo '
';
echo '
';
echo '
';
@@ -413,7 +438,28 @@ private function _renderChartBox( $placeholder_id, $chart_id, $with_filter = fal
$chart_status['title'] = __( 'Click to view the error', 'visualizer' );
}
$shortcode = sprintf( '[visualizer id="%s" class=""]', $chart_id );
- echo '
', esc_html( $title ), '
';
+
+ if ( $this->_isListView() ) {
+ // ── List view: table row ──
+ echo '
';
+ echo '| #' . esc_html( (string) $chart_id ) . ' | ';
+ echo '' . esc_html( $title ) . ' | ';
+ echo '' . ( ! empty( $chart_type ) ? '' . esc_html( $chart_type ) . '' : '—' ) . ' | ';
+ echo '' . esc_html( $shortcode ) . ' | ';
+ echo ' | ';
+ echo '
';
+ return;
+ }
+
+ // ── Grid view: card ──
+ $type_badge = ! empty( $chart_type ) ? '
' . esc_html( $chart_type ) . '' : '';
+ echo '
' . esc_html( $title ) . '' . $type_badge . '
';
if ( Visualizer_Module::is_pro() && $with_filter ) {
echo '
';
echo '
';
@@ -426,14 +472,14 @@ private function _renderChartBox( $placeholder_id, $chart_id, $with_filter = fal
}
echo '
';
}
+ /**
+ * Returns true when the library should render in list (no-preview) mode.
+ *
+ * Priority: ?view= URL param (saves to user meta) → saved user meta → grid default.
+ *
+ * No nonce needed: this is a bookmarkable UI preference URL. A nonce would expire
+ * and break saved/shared links for zero real security gain — the value is allowlisted
+ * to 'list'|'grid' before any write happens.
+ */
+ private function _isListView(): bool {
+ if ( null !== $this->_list_view_cached ) {
+ return $this->_list_view_cached;
+ }
+ if ( isset( $_GET['view'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $view = sanitize_text_field( wp_unslash( $_GET['view'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( in_array( $view, array( 'list', 'grid' ), true ) ) {
+ update_user_meta( get_current_user_id(), 'visualizer_library_view', $view );
+ }
+ $this->_list_view_cached = ( 'list' === $view );
+ } else {
+ $saved = get_user_meta( get_current_user_id(), 'visualizer_library_view', true );
+ $this->_list_view_cached = ( 'list' === $saved );
+ }
+ return $this->_list_view_cached;
+ }
+
+ /**
+ * Returns the HTML for the grid/list view toggle links.
+ */
+ private function _getViewToggleHTML(): string {
+ $is_list = $this->_isListView();
+ $grid_url = esc_url( add_query_arg( 'view', 'grid' ) );
+ $list_url = esc_url( add_query_arg( 'view', 'list' ) );
+ return '
'
+ . '
';
+ }
+
/**
* Render 2-col sidebar
*/
private function _renderSidebar() {
if ( ! Visualizer_Module::is_pro() ) {
- echo '