diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts
index f9089c62e9..c0145b5bd2 100644
--- a/models/tracker/src/index.ts
+++ b/models/tracker/src/index.ts
@@ -1467,7 +1467,8 @@ export function createModel (builder: Builder): void {
         showNested: false
       }
     ],
-    ignoreKeys: ['number', 'estimation', 'attachedTo']
+    ignoreKeys: ['number', 'estimation', 'attachedTo'],
+    getVisibleFilters: tracker.function.GetVisibleFilters
   })
 
   builder.mixin(tracker.class.IssueTemplate, core.class.Class, view.mixin.ClassFilters, {
diff --git a/models/view/src/index.ts b/models/view/src/index.ts
index aeb783a242..a6145d0b73 100644
--- a/models/view/src/index.ts
+++ b/models/view/src/index.ts
@@ -52,6 +52,7 @@ import {
   IgnoreActions,
   InlineAttributEditor,
   KeyBinding,
+  KeyFilter,
   KeyFilterPreset,
   LinkPresenter,
   LinkProvider,
@@ -153,6 +154,7 @@ export class TClassFilters extends TClass implements ClassFilters {
   filters!: (string | KeyFilterPreset)[]
   ignoreKeys?: string[] | undefined
   strict?: boolean | undefined
+  getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>
 }
 
 @Mixin(view.mixin.AttributeFilter, core.class.Class)
diff --git a/plugins/tracker-resources/src/index.ts b/plugins/tracker-resources/src/index.ts
index 44d3bcf2b4..f55dfb8220 100644
--- a/plugins/tracker-resources/src/index.ts
+++ b/plugins/tracker-resources/src/index.ts
@@ -117,7 +117,8 @@ import {
   issueStatusSort,
   moveIssuesToAnotherMilestone,
   milestoneSort,
-  subIssueQuery
+  subIssueQuery,
+  getVisibleFilters
 } from './utils'
 
 import { EmployeeAccount } from '@hcengineering/contact'
@@ -497,7 +498,8 @@ export default async (): Promise<Resources> => ({
     SubIssueQuery: subIssueQuery,
     GetAllPriority: getAllPriority,
     GetAllComponents: getAllComponents,
-    GetAllMilestones: getAllMilestones
+    GetAllMilestones: getAllMilestones,
+    GetVisibleFilters: getVisibleFilters
   },
   actionImpl: {
     Move: move,
diff --git a/plugins/tracker-resources/src/plugin.ts b/plugins/tracker-resources/src/plugin.ts
index 63504a2ecf..8cc0ded299 100644
--- a/plugins/tracker-resources/src/plugin.ts
+++ b/plugins/tracker-resources/src/plugin.ts
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-import { Client, Doc, Ref } from '@hcengineering/core'
+import { Client, Doc, Ref, Space } from '@hcengineering/core'
 import type { Asset, IntlString, Metadata, Resource } from '@hcengineering/platform'
 import { mergeIds } from '@hcengineering/platform'
 import { IssueDraft } from '@hcengineering/tracker'
@@ -24,7 +24,8 @@ import {
   SortFunc,
   Viewlet,
   ViewletDescriptor,
-  ViewQueryAction
+  ViewQueryAction,
+  KeyFilter
 } from '@hcengineering/view'
 import tracker, { trackerId } from '../../tracker/lib'
 
@@ -392,7 +393,8 @@ export default mergeIds(trackerId, tracker, {
     SubIssueQuery: '' as ViewQueryAction,
     GetAllPriority: '' as GetAllValuesFunc,
     GetAllComponents: '' as GetAllValuesFunc,
-    GetAllMilestones: '' as GetAllValuesFunc
+    GetAllMilestones: '' as GetAllValuesFunc,
+    GetVisibleFilters: '' as Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>
   },
   aggregation: {
     CreateComponentAggregationManager: '' as CreateAggregationManagerFunc,
diff --git a/plugins/tracker-resources/src/utils.ts b/plugins/tracker-resources/src/utils.ts
index 5423f5fe1b..9345386234 100644
--- a/plugins/tracker-resources/src/utils.ts
+++ b/plugins/tracker-resources/src/utils.ts
@@ -25,6 +25,7 @@ import core, {
   DocumentUpdate,
   Ref,
   SortingOrder,
+  Space,
   Status,
   StatusCategory,
   StatusManager,
@@ -58,7 +59,7 @@ import {
   MILLISECONDS_IN_WEEK,
   PaletteColorIndexes
 } from '@hcengineering/ui'
-import { ViewletDescriptor } from '@hcengineering/view'
+import { KeyFilter, ViewletDescriptor } from '@hcengineering/view'
 import { CategoryQuery, groupBy, ListSelectionProvider, SelectDirection } from '@hcengineering/view-resources'
 import tracker from './plugin'
 import { defaultPriorities, defaultMilestoneStatuses } from './types'
@@ -654,3 +655,8 @@ export const IssuePriorityColor = {
   [IssuePriority.Medium]: PaletteColorIndexes.Ocean,
   [IssuePriority.Low]: PaletteColorIndexes.Cloud
 }
+
+export async function getVisibleFilters (filters: KeyFilter[], space?: Ref<Space>): Promise<KeyFilter[]> {
+  // Removes the "Project" filter if a specific space is provided
+  return space === undefined ? filters : filters.filter((f) => f.key !== 'space')
+}
diff --git a/plugins/view-resources/src/components/filter/FilterTypePopup.svelte b/plugins/view-resources/src/components/filter/FilterTypePopup.svelte
index 66aff116e7..91da7b364c 100644
--- a/plugins/view-resources/src/components/filter/FilterTypePopup.svelte
+++ b/plugins/view-resources/src/components/filter/FilterTypePopup.svelte
@@ -17,6 +17,7 @@
   import { getClient } from '@hcengineering/presentation'
   import { Label, Scroller, Submenu, closePopup, closeTooltip, resizeObserver, showPopup } from '@hcengineering/ui'
   import { ClassFilters, Filter, KeyFilter, KeyFilterPreset } from '@hcengineering/view'
+  import { getResource } from '@hcengineering/platform'
   import { createEventDispatcher } from 'svelte'
   import { FilterQuery, buildFilterKey } from '../../filter'
   import view from '../../plugin'
@@ -101,12 +102,12 @@
     }
   }
 
-  function getTypes (_class: Ref<Class<Doc>>, nestedFrom: KeyFilter | undefined): KeyFilter[] {
+  async function getTypes (_class: Ref<Class<Doc>>, nestedFrom: KeyFilter | undefined): Promise<KeyFilter[]> {
     let res: KeyFilter[] = []
     if (nestedFrom !== undefined) {
-      res = getNestedTypes(nestedFrom)
+      res = await getNestedTypes(nestedFrom)
     } else {
-      res = getOwnTypes(_class)
+      res = await getOwnTypes(_class)
     }
     res.sort((a, b) => {
       if (a.group === b.group) return 0
@@ -119,20 +120,23 @@
     return res
   }
 
-  function getNestedTypes (type: KeyFilter): KeyFilter[] {
+  async function getNestedTypes (type: KeyFilter): Promise<KeyFilter[]> {
     const targetClass = (hierarchy.getAttribute(type._class, type.key).type as RefTo<Doc>).to
-    return getOwnTypes(targetClass)
+    return await getOwnTypes(targetClass)
   }
 
-  function getOwnTypes (_class: Ref<Class<Doc>>): KeyFilter[] {
+  async function getOwnTypes (_class: Ref<Class<Doc>>): Promise<KeyFilter[]> {
     const mixin = hierarchy.classHierarchyMixin(_class, view.mixin.ClassFilters)
     if (mixin === undefined) return []
     _class = hierarchy.getBaseClass(_class)
     const result = getFilters(_class, mixin)
+    const getVisibleFilters = mixin.getVisibleFilters
+      ? await getResource(mixin.getVisibleFilters)
+      : async (filters: KeyFilter[]) => filters
 
     if (mixin.strict) {
-      // Attributes not specified in "mixing.filters" are ignored
-      return result
+      // Attributes not specified in "mixin.filters" are ignored in "strict" mode
+      return await getVisibleFilters(result, space)
     }
 
     const allAttributes = hierarchy.getAllAttributes(_class)
@@ -166,7 +170,7 @@
       }
     }
 
-    return result
+    return await getVisibleFilters(result, space)
   }
 
   const actionElements: HTMLButtonElement[] = []
@@ -260,8 +264,6 @@
 
   const elements: HTMLElement[] = []
 
-  $: types = getTypes(_class, nestedFrom)
-
   function nextDiffCat (types: KeyFilter[], i: number): boolean {
     if (types[i + 1] === undefined) return false
     return types[i].group !== types[i + 1].group
@@ -289,45 +291,47 @@
       </button>
       <div class="divider" />
     {/if}
-    {#each types as type, i}
-      {#if filter === undefined && hasNested(type)}
-        <Submenu
-          bind:element={elements[i]}
-          on:keydown={(event) => keyDown(event, i)}
-          on:mouseover={() => {
-            elements[i]?.focus()
-          }}
-          label={type.label}
-          props={{
-            _class,
-            space,
-            index,
-            target,
-            onChange,
-            nestedFrom: type
-          }}
-          options={{ component: view.component.FilterTypePopup }}
-          withHover
-        />
-      {:else}
-        <!-- svelte-ignore a11y-mouse-events-have-key-events -->
-        <button
-          class="menu-item"
-          on:keydown={(event) => keyDown(event, i)}
-          on:mouseover={(event) => {
-            event.currentTarget.focus()
-          }}
-          on:click={() => {
-            click(type)
-          }}
-        >
-          <div class="overflow-label pr-1"><Label label={type.label} /></div>
-        </button>
-      {/if}
-      {#if nextDiffCat(types, i)}
-        <div class="menu-separator" />
-      {/if}
-    {/each}
+    {#await getTypes(_class, nestedFrom) then types}
+      {#each types as type, i}
+        {#if filter === undefined && hasNested(type)}
+          <Submenu
+            bind:element={elements[i]}
+            on:keydown={(event) => keyDown(event, i)}
+            on:mouseover={() => {
+              elements[i]?.focus()
+            }}
+            label={type.label}
+            props={{
+              _class,
+              space,
+              index,
+              target,
+              onChange,
+              nestedFrom: type
+            }}
+            options={{ component: view.component.FilterTypePopup }}
+            withHover
+          />
+        {:else}
+          <!-- svelte-ignore a11y-mouse-events-have-key-events -->
+          <button
+            class="menu-item"
+            on:keydown={(event) => keyDown(event, i)}
+            on:mouseover={(event) => {
+              event.currentTarget.focus()
+            }}
+            on:click={() => {
+              click(type)
+            }}
+          >
+            <div class="overflow-label pr-1"><Label label={type.label} /></div>
+          </button>
+        {/if}
+        {#if nextDiffCat(types, i)}
+          <div class="menu-separator" />
+        {/if}
+      {/each}
+    {/await}
   </Scroller>
   <div class="menu-space" />
 </div>
diff --git a/plugins/view/src/index.ts b/plugins/view/src/index.ts
index 1e0d7e9c54..679d4b07a8 100644
--- a/plugins/view/src/index.ts
+++ b/plugins/view/src/index.ts
@@ -128,6 +128,8 @@ export interface ClassFilters extends Class<Doc> {
 
   // Ignore attributes not specified in the "filters" array
   strict?: boolean
+  // Allows to filter out the provided keys, leaving only the necessary ones
+  getVisibleFilters?: Resource<(filters: KeyFilter[], space?: Ref<Space>) => Promise<KeyFilter[]>>
 }
 
 /**