diff --git a/app/react/components/datatables/extend-options/mergeOptions.ts b/app/react/components/datatables/extend-options/mergeOptions.ts
index 0c10ac314..b005ab97d 100644
--- a/app/react/components/datatables/extend-options/mergeOptions.ts
+++ b/app/react/components/datatables/extend-options/mergeOptions.ts
@@ -1,10 +1,10 @@
 import { TableOptions } from '@tanstack/react-table';
 
-type OptionExtender<T> = (options: TableOptions<T>) => TableOptions<T>;
+import { OptionsExtension } from './types';
 
-export function mergeOptions<T>(
-  ...extenders: Array<OptionExtender<T>>
-): OptionExtender<T> {
-  return (options: TableOptions<T>) =>
+export function mergeOptions<D>(
+  ...extenders: Array<OptionsExtension<D>>
+): OptionsExtension<D> {
+  return (options: TableOptions<D>) =>
     extenders.reduce((acc, option) => option(acc), options);
 }
diff --git a/app/react/components/datatables/extend-options/types.ts b/app/react/components/datatables/extend-options/types.ts
new file mode 100644
index 000000000..abe676167
--- /dev/null
+++ b/app/react/components/datatables/extend-options/types.ts
@@ -0,0 +1,3 @@
+import { TableOptions } from '@tanstack/react-table';
+
+export type OptionsExtension<D> = (options: TableOptions<D>) => TableOptions<D>;
diff --git a/app/react/components/datatables/extend-options/withColumnFilters.ts b/app/react/components/datatables/extend-options/withColumnFilters.ts
new file mode 100644
index 000000000..a55705bd5
--- /dev/null
+++ b/app/react/components/datatables/extend-options/withColumnFilters.ts
@@ -0,0 +1,29 @@
+import { ColumnFiltersState, TableOptions } from '@tanstack/react-table';
+
+import { applySetStateAction } from '@/react-tools/apply-set-state-action';
+
+import { DefaultType } from '../types';
+
+import { OptionsExtension } from './types';
+
+export function withColumnFilters<D extends DefaultType>(
+  filters: ColumnFiltersState,
+  onChange: (filters: ColumnFiltersState) => void
+): OptionsExtension<D> {
+  return function extendOptions(options: TableOptions<D>) {
+    return {
+      ...options,
+      state: {
+        ...options.state,
+        columnFilters: filters,
+      },
+      onColumnFiltersChange: (updater) => {
+        onChange(applySetStateAction(updater, filters));
+      },
+      initialState: {
+        ...options.initialState,
+        columnFilters: filters,
+      },
+    };
+  };
+}
diff --git a/app/react/components/datatables/extend-options/withControlledSelected.tsx b/app/react/components/datatables/extend-options/withControlledSelected.tsx
index 58003ee05..f00f5f580 100644
--- a/app/react/components/datatables/extend-options/withControlledSelected.tsx
+++ b/app/react/components/datatables/extend-options/withControlledSelected.tsx
@@ -6,10 +6,12 @@ import {
 
 import { DefaultType } from '../types';
 
+import { OptionsExtension } from './types';
+
 export function withControlledSelected<D extends DefaultType>(
   onChange?: (value: string[]) => void,
   value?: string[]
-) {
+): OptionsExtension<D> {
   return function extendTableOptions(options: TableOptions<D>) {
     if (!onChange || !value) {
       return options;
diff --git a/app/react/components/datatables/extend-options/withGlobalFilter.ts b/app/react/components/datatables/extend-options/withGlobalFilter.ts
index cce2ec24b..59d29be5f 100644
--- a/app/react/components/datatables/extend-options/withGlobalFilter.ts
+++ b/app/react/components/datatables/extend-options/withGlobalFilter.ts
@@ -3,12 +3,14 @@ import { TableOptions } from '@tanstack/react-table';
 import { defaultGlobalFilterFn } from '../Datatable';
 import { DefaultType } from '../types';
 
+import { OptionsExtension } from './types';
+
 export function withGlobalFilter<
   D extends DefaultType,
   TFilter extends {
     search: string;
   },
->(filterFn: typeof defaultGlobalFilterFn<D, TFilter>) {
+>(filterFn: typeof defaultGlobalFilterFn<D, TFilter>): OptionsExtension<D> {
   return function extendOptions(options: TableOptions<D>) {
     return {
       ...options,
diff --git a/app/react/components/datatables/extend-options/withMeta.ts b/app/react/components/datatables/extend-options/withMeta.ts
index cddf02c3f..9434993ad 100644
--- a/app/react/components/datatables/extend-options/withMeta.ts
+++ b/app/react/components/datatables/extend-options/withMeta.ts
@@ -2,7 +2,11 @@ import { TableOptions } from '@tanstack/react-table';
 
 import { DefaultType } from '../types';
 
-export function withMeta<D extends DefaultType>(meta: Record<string, unknown>) {
+import { OptionsExtension } from './types';
+
+export function withMeta<D extends DefaultType>(
+  meta: Record<string, unknown>
+): OptionsExtension<D> {
   return function extendOptions(options: TableOptions<D>) {
     return {
       ...options,
diff --git a/app/react/components/datatables/types.ts b/app/react/components/datatables/types.ts
index 056481921..588d26ad3 100644
--- a/app/react/components/datatables/types.ts
+++ b/app/react/components/datatables/types.ts
@@ -1,5 +1,6 @@
 import { createStore } from 'zustand';
 import { persist } from 'zustand/middleware';
+import { ColumnFiltersState } from '@tanstack/react-table';
 
 import { keyBuilder } from '@/react/hooks/useLocalStorage';
 
@@ -76,6 +77,22 @@ export function refreshableSettings<T extends RefreshableTableSettings>(
   };
 }
 
+export interface FilteredColumnsTableSettings {
+  columnFilters: ColumnFiltersState;
+  setColumnFilters(columns: ColumnFiltersState): void;
+}
+
+export function filteredColumnsSettings<T extends FilteredColumnsTableSettings>(
+  set: ZustandSetFunc<T>
+): FilteredColumnsTableSettings {
+  return {
+    columnFilters: [],
+    setColumnFilters(columns) {
+      set((s) => ({ ...s, columnFilters: columns }));
+    },
+  };
+}
+
 export interface BasicTableSettings
   extends SortableTableSettings,
     PaginationTableSettings {}
diff --git a/app/react/docker/containers/ListView/ContainersDatatable/ContainersDatatable.tsx b/app/react/docker/containers/ListView/ContainersDatatable/ContainersDatatable.tsx
index b7d0ba8f0..7a791a71b 100644
--- a/app/react/docker/containers/ListView/ContainersDatatable/ContainersDatatable.tsx
+++ b/app/react/docker/containers/ListView/ContainersDatatable/ContainersDatatable.tsx
@@ -15,6 +15,8 @@ import {
 } from '@@/datatables/ColumnVisibilityMenu';
 import { TableSettingsProvider } from '@@/datatables/useTableSettings';
 import { useTableState } from '@@/datatables/useTableState';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { useContainers } from '../../queries/containers';
 
@@ -92,6 +94,12 @@ export function ContainersDatatable({
           )}
           dataset={containersQuery.data || []}
           emptyContentLabel="No containers found"
+          extendTableOptions={mergeOptions(
+            withColumnFilters(
+              tableState.columnFilters,
+              tableState.setColumnFilters
+            )
+          )}
         />
       </TableSettingsProvider>
     </RowProvider>
diff --git a/app/react/docker/containers/ListView/ContainersDatatable/datatable-store.ts b/app/react/docker/containers/ListView/ContainersDatatable/datatable-store.ts
index 1a45ca67e..3c4877661 100644
--- a/app/react/docker/containers/ListView/ContainersDatatable/datatable-store.ts
+++ b/app/react/docker/containers/ListView/ContainersDatatable/datatable-store.ts
@@ -2,6 +2,7 @@ import {
   refreshableSettings,
   hiddenColumnsSettings,
   createPersistedStore,
+  filteredColumnsSettings,
 } from '@@/datatables/types';
 
 import { QuickAction, TableSettings } from './types';
@@ -12,6 +13,7 @@ export function createStore(storageKey: string) {
   return createPersistedStore<TableSettings>(storageKey, 'name', (set) => ({
     ...hiddenColumnsSettings(set),
     ...refreshableSettings(set),
+    ...filteredColumnsSettings(set),
     truncateContainerName: TRUNCATE_LENGTH,
     setTruncateContainerName(truncateContainerName: number) {
       set({
diff --git a/app/react/docker/containers/ListView/ContainersDatatable/types.ts b/app/react/docker/containers/ListView/ContainersDatatable/types.ts
index b2cc66deb..ec1919034 100644
--- a/app/react/docker/containers/ListView/ContainersDatatable/types.ts
+++ b/app/react/docker/containers/ListView/ContainersDatatable/types.ts
@@ -1,5 +1,6 @@
 import {
   BasicTableSettings,
+  FilteredColumnsTableSettings,
   RefreshableTableSettings,
   SettableColumnsTableSettings,
 } from '@@/datatables/types';
@@ -15,7 +16,8 @@ export interface TableSettings
   extends BasicTableSettings,
     SettableColumnsTableSettings,
     SettableQuickActionsTableSettings<QuickAction>,
-    RefreshableTableSettings {
+    RefreshableTableSettings,
+    FilteredColumnsTableSettings {
   truncateContainerName: number;
   setTruncateContainerName: (value: number) => void;
 }
diff --git a/app/react/docker/images/ListView/ImagesDatatable/ImagesDatatable.tsx b/app/react/docker/images/ListView/ImagesDatatable/ImagesDatatable.tsx
index dfa0da397..2fd0ed8c8 100644
--- a/app/react/docker/images/ListView/ImagesDatatable/ImagesDatatable.tsx
+++ b/app/react/docker/images/ListView/ImagesDatatable/ImagesDatatable.tsx
@@ -10,6 +10,8 @@ import { Datatable, TableSettingsMenu } from '@@/datatables';
 import {
   BasicTableSettings,
   createPersistedStore,
+  FilteredColumnsTableSettings,
+  filteredColumnsSettings,
   refreshableSettings,
   RefreshableTableSettings,
 } from '@@/datatables/types';
@@ -18,6 +20,8 @@ import { AddButton, Button, ButtonGroup, LoadingButton } from '@@/buttons';
 import { Link } from '@@/Link';
 import { ButtonWithRef } from '@@/buttons/Button';
 import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { ImagesListResponse, useImages } from '../../queries/useImages';
 
@@ -28,13 +32,15 @@ const tableKey = 'images';
 
 export interface TableSettings
   extends BasicTableSettings,
-    RefreshableTableSettings {}
+    RefreshableTableSettings,
+    FilteredColumnsTableSettings {}
 
 const settingsStore = createPersistedStore<TableSettings>(
   tableKey,
   'tags',
   (set) => ({
     ...refreshableSettings(set),
+    ...filteredColumnsSettings(set),
   })
 );
 
@@ -65,6 +71,9 @@ export function ImagesDatatable({
       title="Images"
       titleIcon={List}
       data-cy="docker-images-datatable"
+      extendTableOptions={mergeOptions(
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
       renderTableActions={(selectedItems) => (
         <div className="flex items-center gap-2">
           <RemoveButtonMenu selectedItems={selectedItems} onRemove={onRemove} />
diff --git a/app/react/docker/services/ItemView/TasksDatatable/TasksDatatable.tsx b/app/react/docker/services/ItemView/TasksDatatable/TasksDatatable.tsx
index bcd533621..5d1ce33b9 100644
--- a/app/react/docker/services/ItemView/TasksDatatable/TasksDatatable.tsx
+++ b/app/react/docker/services/ItemView/TasksDatatable/TasksDatatable.tsx
@@ -1,15 +1,24 @@
 import { List } from 'lucide-react';
 
 import { Datatable } from '@@/datatables';
-import { createPersistedStore } from '@@/datatables/types';
-import { useTableState } from '@@/datatables/useTableState';
+import {
+  BasicTableSettings,
+  type FilteredColumnsTableSettings,
+  filteredColumnsSettings,
+} from '@@/datatables/types';
+import { useTableStateWithStorage } from '@@/datatables/useTableState';
 import { withMeta } from '@@/datatables/extend-options/withMeta';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { useColumns } from './columns';
 import { DecoratedTask } from './types';
 
 const storageKey = 'docker-service-tasks';
-const store = createPersistedStore(storageKey);
+
+interface TableSettings
+  extends BasicTableSettings,
+    FilteredColumnsTableSettings {}
 
 export function TasksDatatable({
   dataset,
@@ -20,7 +29,13 @@ export function TasksDatatable({
   isSlotColumnVisible: boolean;
   serviceName: string;
 }) {
-  const tableState = useTableState(store, storageKey);
+  const tableState = useTableStateWithStorage<TableSettings>(
+    storageKey,
+    undefined,
+    (set) => ({
+      ...filteredColumnsSettings(set),
+    })
+  );
   const columns = useColumns(isSlotColumnVisible);
 
   return (
@@ -31,7 +46,11 @@ export function TasksDatatable({
       columns={columns}
       dataset={dataset}
       emptyContentLabel="No task available."
-      extendTableOptions={withMeta({ table: 'tasks', serviceName })}
+      extendTableOptions={mergeOptions(
+        withMeta({ table: 'tasks', serviceName }),
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
+      disableSelect
       data-cy="docker-service-tasks-datatable"
     />
   );
diff --git a/app/react/docker/stacks/ListView/StacksDatatable/StacksDatatable.tsx b/app/react/docker/stacks/ListView/StacksDatatable/StacksDatatable.tsx
index 7ff0bcf15..8a660e0b6 100644
--- a/app/react/docker/stacks/ListView/StacksDatatable/StacksDatatable.tsx
+++ b/app/react/docker/stacks/ListView/StacksDatatable/StacksDatatable.tsx
@@ -5,22 +5,20 @@ import { useAuthorizations, useIsEdgeAdmin } from '@/react/hooks/useUser';
 import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
 
 import { Datatable } from '@@/datatables';
-import { useTableState } from '@@/datatables/useTableState';
 import { useRepeater } from '@@/datatables/useRepeater';
 import { defaultGlobalFilterFn } from '@@/datatables/Datatable';
 import { withGlobalFilter } from '@@/datatables/extend-options/withGlobalFilter';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { isExternalStack, isOrphanedStack } from '../../view-models/utils';
 
 import { TableActions } from './TableActions';
 import { TableSettingsMenus } from './TableSettingsMenus';
-import { createStore } from './store';
+import { useStore } from './store';
 import { useColumns } from './columns';
 import { DecoratedStack } from './types';
 
-const tableKey = 'docker_stacks';
-const settingsStore = createStore(tableKey);
-
 export function StacksDatatable({
   onRemove,
   onReload,
@@ -32,7 +30,7 @@ export function StacksDatatable({
   isImageNotificationEnabled: boolean;
   dataset: Array<DecoratedStack>;
 }) {
-  const tableState = useTableState(settingsStore, tableKey);
+  const tableState = useStore();
   useRepeater(tableState.autoRefreshRate, onReload);
   const isAdminQuery = useIsEdgeAdmin();
   const { authorized: canManageStacks } = useAuthorizations([
@@ -69,7 +67,10 @@ export function StacksDatatable({
           tableState.hiddenColumns.map((col) => [col, false])
         ),
       }}
-      extendTableOptions={withGlobalFilter(globalFilterFn)}
+      extendTableOptions={mergeOptions(
+        withGlobalFilter(globalFilterFn),
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
       data-cy="docker-stacks-datatable"
     />
   );
diff --git a/app/react/docker/stacks/ListView/StacksDatatable/store.ts b/app/react/docker/stacks/ListView/StacksDatatable/store.ts
index 25f2743b3..6546be685 100644
--- a/app/react/docker/stacks/ListView/StacksDatatable/store.ts
+++ b/app/react/docker/stacks/ListView/StacksDatatable/store.ts
@@ -1,24 +1,30 @@
 import {
-  BasicTableSettings,
-  RefreshableTableSettings,
-  SettableColumnsTableSettings,
-  createPersistedStore,
+  type BasicTableSettings,
+  type FilteredColumnsTableSettings,
+  type RefreshableTableSettings,
+  type SettableColumnsTableSettings,
   hiddenColumnsSettings,
   refreshableSettings,
+  filteredColumnsSettings,
 } from '@@/datatables/types';
+import { useTableStateWithStorage } from '@@/datatables/useTableState';
 
 export interface TableSettings
   extends BasicTableSettings,
     SettableColumnsTableSettings,
-    RefreshableTableSettings {
+    RefreshableTableSettings,
+    FilteredColumnsTableSettings {
   showOrphanedStacks: boolean;
   setShowOrphanedStacks(value: boolean): void;
 }
 
-export function createStore(storageKey: string) {
-  return createPersistedStore<TableSettings>(storageKey, 'name', (set) => ({
+const tableKey = 'docker_stacks';
+
+export function useStore() {
+  return useTableStateWithStorage<TableSettings>(tableKey, 'name', (set) => ({
     ...hiddenColumnsSettings(set),
     ...refreshableSettings(set),
+    ...filteredColumnsSettings(set),
     showOrphanedStacks: false,
     setShowOrphanedStacks(showOrphanedStacks) {
       set((s) => ({ ...s, showOrphanedStacks }));
diff --git a/app/react/docker/volumes/ListView/VolumesDatatable/VolumesDatatable.tsx b/app/react/docker/volumes/ListView/VolumesDatatable/VolumesDatatable.tsx
index f236562aa..186af476d 100644
--- a/app/react/docker/volumes/ListView/VolumesDatatable/VolumesDatatable.tsx
+++ b/app/react/docker/volumes/ListView/VolumesDatatable/VolumesDatatable.tsx
@@ -4,6 +4,8 @@ import { Datatable, TableSettingsMenu } from '@@/datatables';
 import { TableSettingsMenuAutoRefresh } from '@@/datatables/TableSettingsMenuAutoRefresh';
 import {
   BasicTableSettings,
+  FilteredColumnsTableSettings,
+  filteredColumnsSettings,
   RefreshableTableSettings,
   createPersistedStore,
   refreshableSettings,
@@ -11,13 +13,17 @@ import {
 import { useRepeater } from '@@/datatables/useRepeater';
 import { useTableState } from '@@/datatables/useTableState';
 import { withMeta } from '@@/datatables/extend-options/withMeta';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { DecoratedVolume } from '../types';
 
 import { TableActions } from './TableActions';
 import { useColumns } from './columns';
 
-interface TableSettings extends BasicTableSettings, RefreshableTableSettings {}
+interface TableSettings
+  extends BasicTableSettings,
+    RefreshableTableSettings,
+    FilteredColumnsTableSettings {}
 
 const storageKey = 'docker-volumes';
 const store = createPersistedStore<TableSettings>(
@@ -25,6 +31,7 @@ const store = createPersistedStore<TableSettings>(
   undefined,
   (set) => ({
     ...refreshableSettings(set),
+    ...filteredColumnsSettings(set),
   })
 );
 
@@ -63,10 +70,16 @@ export function VolumesDatatable({
           />
         </TableSettingsMenu>
       )}
-      extendTableOptions={withMeta({
-        table: 'volumes',
-        isBrowseVisible,
-      })}
+      extendTableOptions={
+        (withMeta({
+          table: 'volumes',
+          isBrowseVisible,
+        }),
+        withColumnFilters(
+          tableState.columnFilters,
+          tableState.setColumnFilters
+        ))
+      }
       data-cy="docker-volumes-datatable"
     />
   );
diff --git a/app/react/hooks/useUnauthorizedRedirect.ts b/app/react/hooks/useUnauthorizedRedirect.ts
index 1a181e05d..d7b2a1d8c 100644
--- a/app/react/hooks/useUnauthorizedRedirect.ts
+++ b/app/react/hooks/useUnauthorizedRedirect.ts
@@ -10,7 +10,7 @@ type AuthorizationOptions = {
 
 type RedirectOptions = {
   to: string;
-  params: Record<string, unknown>;
+  params?: Record<string, unknown>;
 };
 
 /**
diff --git a/app/react/kubernetes/configs/ListView/ConfigMapsDatatable/ConfigMapsDatatable.tsx b/app/react/kubernetes/configs/ListView/ConfigMapsDatatable/ConfigMapsDatatable.tsx
index 39cdbd1bb..8f2942920 100644
--- a/app/react/kubernetes/configs/ListView/ConfigMapsDatatable/ConfigMapsDatatable.tsx
+++ b/app/react/kubernetes/configs/ListView/ConfigMapsDatatable/ConfigMapsDatatable.tsx
@@ -5,8 +5,11 @@ import { CronJob, Job } from 'kubernetes-types/batch/v1';
 
 import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
 import { Authorized, useAuthorizations } from '@/react/hooks/useUser';
-import { DefaultDatatableSettings } from '@/react/kubernetes/datatables/DefaultDatatableSettings';
-import { createStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
+import {
+  DefaultDatatableSettings,
+  TableSettings as KubeTableSettings,
+} from '@/react/kubernetes/datatables/DefaultDatatableSettings';
+import { useKubeStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
 import { SystemResourceDescription } from '@/react/kubernetes/datatables/SystemResourceDescription';
 import { pluralize } from '@/portainer/helpers/strings';
 import { useNamespacesQuery } from '@/react/kubernetes/namespaces/queries/useNamespacesQuery';
@@ -17,9 +20,14 @@ import { useJobs } from '@/react/kubernetes/applications/useJobs';
 import { useCronJobs } from '@/react/kubernetes/applications/useCronJobs';
 
 import { Datatable, TableSettingsMenu } from '@@/datatables';
-import { useTableState } from '@@/datatables/useTableState';
+import { AddButton } from '@@/buttons';
 import { DeleteButton } from '@@/buttons/DeleteButton';
-import { AddButton } from '@@/buttons/AddButton';
+import {
+  type FilteredColumnsTableSettings,
+  filteredColumnsSettings,
+} from '@@/datatables/types';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import {
   useConfigMapsForCluster,
@@ -31,11 +39,20 @@ import { getIsConfigMapInUse } from './utils';
 import { ConfigMapRowData } from './types';
 import { columns } from './columns';
 
+interface TableSettings
+  extends KubeTableSettings,
+    FilteredColumnsTableSettings {}
+
 const storageKey = 'k8sConfigMapsDatatable';
-const settingsStore = createStore(storageKey);
 
 export function ConfigMapsDatatable() {
-  const tableState = useTableState(settingsStore, storageKey);
+  const tableState = useKubeStore<TableSettings>(
+    storageKey,
+    undefined,
+    (set) => ({
+      ...filteredColumnsSettings(set),
+    })
+  );
   const { authorized: canWrite } = useAuthorizations(['K8sConfigMapsW']);
   const readOnly = !canWrite;
   const { authorized: canAccessSystemResources } = useAuthorizations(
@@ -109,6 +126,9 @@ export function ConfigMapsDatatable() {
         />
       }
       data-cy="k8s-configmaps-datatable"
+      extendTableOptions={mergeOptions(
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
     />
   );
 }
diff --git a/app/react/kubernetes/configs/ListView/SecretsDatatable/SecretsDatatable.tsx b/app/react/kubernetes/configs/ListView/SecretsDatatable/SecretsDatatable.tsx
index 704a58c61..f0e560696 100644
--- a/app/react/kubernetes/configs/ListView/SecretsDatatable/SecretsDatatable.tsx
+++ b/app/react/kubernetes/configs/ListView/SecretsDatatable/SecretsDatatable.tsx
@@ -5,8 +5,11 @@ import { CronJob, Job } from 'kubernetes-types/batch/v1';
 
 import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
 import { Authorized, useAuthorizations } from '@/react/hooks/useUser';
-import { DefaultDatatableSettings } from '@/react/kubernetes/datatables/DefaultDatatableSettings';
-import { createStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
+import {
+  DefaultDatatableSettings,
+  TableSettings as KubeTableSettings,
+} from '@/react/kubernetes/datatables/DefaultDatatableSettings';
+import { useKubeStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
 import { SystemResourceDescription } from '@/react/kubernetes/datatables/SystemResourceDescription';
 import { pluralize } from '@/portainer/helpers/strings';
 import { useNamespacesQuery } from '@/react/kubernetes/namespaces/queries/useNamespacesQuery';
@@ -18,8 +21,13 @@ import { useCronJobs } from '@/react/kubernetes/applications/useCronJobs';
 
 import { Datatable, TableSettingsMenu } from '@@/datatables';
 import { AddButton } from '@@/buttons';
-import { useTableState } from '@@/datatables/useTableState';
 import { DeleteButton } from '@@/buttons/DeleteButton';
+import {
+  type FilteredColumnsTableSettings,
+  filteredColumnsSettings,
+} from '@@/datatables/types';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import {
   useSecretsForCluster,
@@ -32,17 +40,26 @@ import { SecretRowData } from './types';
 import { columns } from './columns';
 
 const storageKey = 'k8sSecretsDatatable';
-const settingsStore = createStore(storageKey);
+
+interface TableSettings
+  extends KubeTableSettings,
+    FilteredColumnsTableSettings {}
 
 export function SecretsDatatable() {
-  const tableState = useTableState(settingsStore, storageKey);
+  const tableState = useKubeStore<TableSettings>(
+    storageKey,
+    undefined,
+    (set) => ({
+      ...filteredColumnsSettings(set),
+    })
+  );
+  const environmentId = useEnvironmentId();
   const { authorized: canWrite } = useAuthorizations(['K8sSecretsW']);
   const readOnly = !canWrite;
   const { authorized: canAccessSystemResources } = useAuthorizations(
     'K8sAccessSystemNamespaces'
   );
 
-  const environmentId = useEnvironmentId();
   const { data: namespaces, ...namespacesQuery } = useNamespacesQuery(
     environmentId,
     {
@@ -109,6 +126,9 @@ export function SecretsDatatable() {
         />
       }
       data-cy="k8s-secrets-datatable"
+      extendTableOptions={mergeOptions(
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
     />
   );
 }
diff --git a/app/react/kubernetes/ingresses/IngressDatatable/IngressDatatable.tsx b/app/react/kubernetes/ingresses/IngressDatatable/IngressDatatable.tsx
index 040e31204..cbd31eb81 100644
--- a/app/react/kubernetes/ingresses/IngressDatatable/IngressDatatable.tsx
+++ b/app/react/kubernetes/ingresses/IngressDatatable/IngressDatatable.tsx
@@ -4,14 +4,22 @@ import { useMemo } from 'react';
 import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
 import { useAuthorizations, Authorized } from '@/react/hooks/useUser';
 import Route from '@/assets/ico/route.svg?c';
-import { DefaultDatatableSettings } from '@/react/kubernetes/datatables/DefaultDatatableSettings';
-import { createStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
+import {
+  DefaultDatatableSettings,
+  TableSettings as KubeTableSettings,
+} from '@/react/kubernetes/datatables/DefaultDatatableSettings';
+import { useKubeStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
 import { SystemResourceDescription } from '@/react/kubernetes/datatables/SystemResourceDescription';
 
 import { Datatable, TableSettingsMenu } from '@@/datatables';
 import { AddButton } from '@@/buttons';
-import { useTableState } from '@@/datatables/useTableState';
 import { DeleteButton } from '@@/buttons/DeleteButton';
+import {
+  type FilteredColumnsTableSettings,
+  filteredColumnsSettings,
+} from '@@/datatables/types';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import { DeleteIngressesRequest, Ingress } from '../types';
 import { useDeleteIngresses, useIngresses } from '../queries';
@@ -29,10 +37,18 @@ interface SelectedIngress {
 }
 const storageKey = 'ingressClassesNameSpace';
 
-const settingsStore = createStore(storageKey);
+interface TableSettings
+  extends KubeTableSettings,
+    FilteredColumnsTableSettings {}
 
 export function IngressDatatable() {
-  const tableState = useTableState(settingsStore, storageKey);
+  const tableState = useKubeStore<TableSettings>(
+    storageKey,
+    undefined,
+    (set) => ({
+      ...filteredColumnsSettings(set),
+    })
+  );
   const environmentId = useEnvironmentId();
 
   const { authorized: canAccessSystemResources } = useAuthorizations(
@@ -91,6 +107,9 @@ export function IngressDatatable() {
       }
       disableSelect={useCheckboxes()}
       data-cy="k8s-ingresses-datatable"
+      extendTableOptions={mergeOptions(
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
     />
   );
 
diff --git a/app/react/kubernetes/services/ServicesView/ServicesDatatable/ServicesDatatable.tsx b/app/react/kubernetes/services/ServicesView/ServicesDatatable/ServicesDatatable.tsx
index 000308852..193859fc9 100644
--- a/app/react/kubernetes/services/ServicesView/ServicesDatatable/ServicesDatatable.tsx
+++ b/app/react/kubernetes/services/ServicesView/ServicesDatatable/ServicesDatatable.tsx
@@ -9,14 +9,23 @@ import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
 import { Authorized, useAuthorizations } from '@/react/hooks/useUser';
 import { notifyError, notifySuccess } from '@/portainer/services/notifications';
 import { pluralize } from '@/portainer/helpers/strings';
-import { DefaultDatatableSettings } from '@/react/kubernetes/datatables/DefaultDatatableSettings';
+import {
+  DefaultDatatableSettings,
+  TableSettings as KubeTableSettings,
+} from '@/react/kubernetes/datatables/DefaultDatatableSettings';
+import { useKubeStore } from '@/react/kubernetes/datatables/default-kube-datatable-store';
 import { SystemResourceDescription } from '@/react/kubernetes/datatables/SystemResourceDescription';
 import { useNamespacesQuery } from '@/react/kubernetes/namespaces/queries/useNamespacesQuery';
 import { CreateFromManifestButton } from '@/react/kubernetes/components/CreateFromManifestButton';
 
 import { Datatable, Table, TableSettingsMenu } from '@@/datatables';
-import { useTableState } from '@@/datatables/useTableState';
 import { DeleteButton } from '@@/buttons/DeleteButton';
+import {
+  type FilteredColumnsTableSettings,
+  filteredColumnsSettings,
+} from '@@/datatables/types';
+import { mergeOptions } from '@@/datatables/extend-options/mergeOptions';
+import { withColumnFilters } from '@@/datatables/extend-options/withColumnFilters';
 
 import {
   useMutationDeleteServices,
@@ -25,13 +34,20 @@ import {
 import { Service } from '../../types';
 
 import { columns } from './columns';
-import { createStore } from './datatable-store';
 
 const storageKey = 'k8sServicesDatatable';
-const settingsStore = createStore(storageKey);
+interface TableSettings
+  extends KubeTableSettings,
+    FilteredColumnsTableSettings {}
 
 export function ServicesDatatable() {
-  const tableState = useTableState(settingsStore, storageKey);
+  const tableState = useKubeStore<TableSettings>(
+    storageKey,
+    undefined,
+    (set) => ({
+      ...filteredColumnsSettings(set),
+    })
+  );
   const environmentId = useEnvironmentId();
   const { data: namespaces, ...namespacesQuery } =
     useNamespacesQuery(environmentId);
@@ -91,6 +107,9 @@ export function ServicesDatatable() {
       }
       renderRow={servicesRenderRow}
       data-cy="k8s-services-datatable"
+      extendTableOptions={mergeOptions(
+        withColumnFilters(tableState.columnFilters, tableState.setColumnFilters)
+      )}
     />
   );
 }