diff --git a/package-lock.json b/package-lock.json
index dfb6cc6789998183cba2caf217d2bc96e73b1e38..01d7a20c1712d729258e6610fc6a25941d73b352 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1690,32 +1690,59 @@
       }
     },
     "node_modules/@primevue/core": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.0.5.tgz",
-      "integrity": "sha512-DUCslDA93eUOVW0A1I3yoZgRLI4zmI2++loZQXbUF5jaXCwKiAza14+iyUU+cWH27VSq+jQnCEP9QJtPZiJJ0w==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.2.1.tgz",
+      "integrity": "sha512-L81TZSZU8zRznIi2g6IWwlZ5wraaE8DrNUJyxieCRCTpbSF3rSlYmhDEuzal8PfE0RuvXpRsxqedTHxz5cdqPg==",
       "dependencies": {
-        "@primeuix/styled": "^0.0.5",
-        "@primeuix/utils": "^0.0.5"
+        "@primeuix/styled": "^0.3.0",
+        "@primeuix/utils": "^0.3.0"
       },
       "engines": {
         "node": ">=12.11.0"
       },
       "peerDependencies": {
-        "vue": "^3.0.0"
+        "vue": "^3.3.0"
+      }
+    },
+    "node_modules/@primevue/core/node_modules/@primeuix/styled": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.3.0.tgz",
+      "integrity": "sha512-XsLbmyM1u50A0EDATIHyqm5O/zOCSyNKPk4pNN8HFvEPehbsjf4tkXcRZAyaVvntSCLpV4XGAj7v5EDCQkBRlg==",
+      "dependencies": {
+        "@primeuix/utils": "^0.3.0"
+      },
+      "engines": {
+        "node": ">=12.11.0"
+      }
+    },
+    "node_modules/@primevue/core/node_modules/@primeuix/utils": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.3.0.tgz",
+      "integrity": "sha512-d6ymWez1n+iqwzAVhyOTmrOHl5qnSX2oGlTy97qGuA15gLai+MQaxONHFNdDia8Q7o396v7KK9IvhAx9VET/+A==",
+      "engines": {
+        "node": ">=12.11.0"
       }
     },
     "node_modules/@primevue/icons": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.0.5.tgz",
-      "integrity": "sha512-ZxR9W1wlAE2fTtUhrHyeMx5t0jNyAgxDcHPm0cNXpX8q1XF95rSM/qb48QKXIBDBrJ/xs57BcyCNADP/VDPY4g==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.2.1.tgz",
+      "integrity": "sha512-TOhxgkcmgBqmlHlf2x+gs4874iHopkow0gRAC5FztZTgTZQrqy8hPIA9b4O1lW7P6GOjGuVIwSH8y2lw6Q8koA==",
       "dependencies": {
-        "@primeuix/utils": "^0.0.5",
-        "@primevue/core": "4.0.5"
+        "@primeuix/utils": "^0.3.0",
+        "@primevue/core": "4.2.1"
       },
       "engines": {
         "node": ">=12.11.0"
       }
     },
+    "node_modules/@primevue/icons/node_modules/@primeuix/utils": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.3.0.tgz",
+      "integrity": "sha512-d6ymWez1n+iqwzAVhyOTmrOHl5qnSX2oGlTy97qGuA15gLai+MQaxONHFNdDia8Q7o396v7KK9IvhAx9VET/+A==",
+      "engines": {
+        "node": ">=12.11.0"
+      }
+    },
     "node_modules/@primevue/themes": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/@primevue/themes/-/themes-4.0.5.tgz",
@@ -8374,19 +8401,38 @@
       }
     },
     "node_modules/primevue": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.0.5.tgz",
-      "integrity": "sha512-MALszGIZ5SnEQy1XeZLBFhpMXQ1OS7D1U7H+l/JAX5U46RQ1vufo7NAiWbbV5/ADjPGw4uLplqMQxujkksNY2g==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/primevue/-/primevue-4.2.1.tgz",
+      "integrity": "sha512-cU9ZQVq9fitsQEIrfGeIl7xELBn61JCMxWkzcS9dkr165g29AvUrUNS9ufs1t2NoMJzE8VllwzweF/tSFAr2cw==",
       "dependencies": {
-        "@primeuix/styled": "^0.0.5",
-        "@primeuix/utils": "^0.0.5",
-        "@primevue/core": "4.0.5",
-        "@primevue/icons": "4.0.5"
+        "@primeuix/styled": "^0.3.0",
+        "@primeuix/utils": "^0.3.0",
+        "@primevue/core": "4.2.1",
+        "@primevue/icons": "4.2.1"
       },
       "engines": {
         "node": ">=12.11.0"
       }
     },
+    "node_modules/primevue/node_modules/@primeuix/styled": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.3.0.tgz",
+      "integrity": "sha512-XsLbmyM1u50A0EDATIHyqm5O/zOCSyNKPk4pNN8HFvEPehbsjf4tkXcRZAyaVvntSCLpV4XGAj7v5EDCQkBRlg==",
+      "dependencies": {
+        "@primeuix/utils": "^0.3.0"
+      },
+      "engines": {
+        "node": ">=12.11.0"
+      }
+    },
+    "node_modules/primevue/node_modules/@primeuix/utils": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.3.0.tgz",
+      "integrity": "sha512-d6ymWez1n+iqwzAVhyOTmrOHl5qnSX2oGlTy97qGuA15gLai+MQaxONHFNdDia8Q7o396v7KK9IvhAx9VET/+A==",
+      "engines": {
+        "node": ">=12.11.0"
+      }
+    },
     "node_modules/process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
diff --git a/src/assets/communityExample1.ts b/src/assets/communityExample1.ts
new file mode 100644
index 0000000000000000000000000000000000000000..73028a07e765b7a8fe4d7487c43aea65fa3564b3
--- /dev/null
+++ b/src/assets/communityExample1.ts
@@ -0,0 +1,34 @@
+import type { OcCommunity } from "@/declarations";
+
+export const communityExample1: OcCommunity = {
+  "@id": "https://www.irit.fr/opencommon/communities/189088ec-baa9-4397-8c6f-eefde9a3790c",
+  "@type": [
+    "http://www.w3.org/ns/dcat#Catalog",
+    "http://www.w3.org/2002/07/owl#NamedIndividual",
+    "https://www.irit.fr/opencommon/system/Space",
+    "https://www.irit.fr/opencommon/terms/Space",
+    "https://www.irit.fr/opencommon/terms/Community",
+    "http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"
+  ],
+  "abstract": {
+    "en": "Laureate of the Laboratory for Excellence project (LabEx) in the program « Investment in the future », the DRIIHM LabEx, Device for Interdisciplinary Research on human-environments Interactions, aggregate 13 human-environments observatories (OHM in french), tools for observing socio-ecosystems impacted by anthropic events. Created by CNRS-INEE in 2007, they are located in metropolitan France, overseas France and abroad.",
+    "fr": "Lauréat de la deuxième vague de l'appel à projet Laboratoire d'Excellence (LabEx) dans le cadre du programme « Investissements d'avenir », le LabEx DRIIHM, Dispositif de Recherche Interdisciplinaire sur les Interactions Hommes-Milieux, regroupe à ce jour 13 Observatoires Hommes-Milieux, outils d'observation de socio-écosystèmes impactés par un événement d'origine anthropique. Créés par le CNRS-INEE en 2007, ils sont répartis en France métropolitaine, en outre-mer et à l’étranger."
+  }, "description": {
+    "en": "InterDisciplinary Research Facility aggregating 13 human-environments observatories (OHM).",
+    "fr": "Dispositif de Recherche Interdisciplinaire avec ses 13 Observatoires Hommes-Milieux (OHM)."
+  },
+  "identifier": "189088ec-baa9-4397-8c6f-eefde9a3790c",
+  "title": {
+    "fr": "Labex DRIIHM",
+    "en": "DRIIHM"
+  },
+  "catalog": [
+    "https://www.irit.fr/opencommon/resourceTree/MyResources",
+    "https://opencommon.irit.fr/catalogs/6B8E175A-8C94-11EF-A39A-D6E96336453A",
+    "https://opencommon.irit.fr/catalogs/AF1A5FAE-8C91-11EF-A39A-D6E96336453A"
+  ],
+  "logo": "https://www.driihm.fr/images/images/logos_png/logo_DRIIHM_r%C3%A9duit.png",
+  "name": "driihm",
+  "isSpaceOf": "https://www.irit.fr/opencommon/agents/organization/9a20f121-c64e-4049-93a7-4bedbe819fd6",
+  "color": "olivine",
+}
\ No newline at end of file
diff --git a/src/components/DashboardDataset/DashboardDataset.stories.ts b/src/components/DashboardDataset/DashboardDataset.stories.ts
index 0038574ae60b9339aef0486daed9d7f69ce883dd..f47adee2a2092b2bc035e068520f92d4c55b009a 100644
--- a/src/components/DashboardDataset/DashboardDataset.stories.ts
+++ b/src/components/DashboardDataset/DashboardDataset.stories.ts
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/vue3';
 import DashboardDataset from './DashboardDataset.vue';
 import { datasetSummaries, distributionSummaries } from './exampleSummaries'
 import type { OcDatasetSummary } from '@/declarations';
+import { communityExample1 } from '@/assets/communityExample1';
 
 const meta: Meta<typeof DashboardDataset> = {
   component: DashboardDataset,
@@ -20,19 +21,7 @@ export const Default: Story = {
     template: '<DashboardDataset v-bind="args" />',
   }),
   args: {
-    community: {
-      "@id": "https://www.irit.fr/distributions/7f452387-c7ef-4928-b776-b5c3f9080769",
-      "@type": ["oc:Space"],
-      name: 'driihm',
-      abstract: { "en": "Laureate of the Laboratory for Excellence project (LabEx) in the program « Investment in the future », the DRIIHM LabEx, Device for Interdisciplinary Research on human-environments Interactions, aggregate 13 human-environments observatories (OHM in french), tools for observing socio-ecosystems impacted by anthropic events. Created by CNRS-INEE in 2007, they are located in metropolitan France, overseas France and abroad.", "fr": "Lauréat de la deuxième vague de l'appel à projet Laboratoire d'Excellence (LabEx) dans le cadre du programme « Investissements d'avenir », le LabEx DRIIHM, Dispositif de Recherche Interdisciplinaire sur les Interactions Hommes-Milieux, regroupe à ce jour 13 Observatoires Hommes-Milieux, outils d'observation de socio-écosystèmes impactés par un événement d'origine anthropique. Créés par le CNRS-INEE en 2007, ils sont répartis en France métropolitaine, en outre-mer et à l’étranger." },
-      identifier: "189088ec-baa9-4397-8c6f-eefde9a3790c",
-      title: {
-        fr: "Communauté du LabEx DRIIHM",
-        en: "DRIIHM Community"
-      },
-      isSpaceOf: "https://www.irit.fr/opencommon/agents/organization/9a20f121-c64e-4049-93a7-4bedbe819fd6",
-      color: 'linen'
-    },
+    community: communityExample1,
     datasets: datasetSummaries as OcDatasetSummary[],
     distributionsCallback: (_: string[]) => new Promise((resolve) => {
       setTimeout(() => {
diff --git a/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.stories.ts b/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b14698ff806d58620e8bad138e9cc4df9a178d7a
--- /dev/null
+++ b/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.stories.ts
@@ -0,0 +1,30 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+
+import OcDatasetFormStep2 from './OcDatasetFormStep2.vue';
+import { communityExample1 } from '@/assets/communityExample1';
+
+const meta: Meta<typeof OcDatasetFormStep2> = {
+  component: OcDatasetFormStep2,
+};
+
+export default meta;
+type Story = StoryObj<typeof OcDatasetFormStep2>;
+
+export const Default: Story = {
+  render: (args) => ({
+    components: { OcDatasetFormStep2 },
+    setup() {
+      return { args };
+    },
+    template: '<OcDatasetFormStep2 v-bind="args" />',
+  }),
+  args: {
+    modelValue: {},
+    community: communityExample1,
+    userPrivateGraph: 'private-graph',
+    auth: {
+      email: import.meta.env.VITE_VISITOR_USER,
+      password: import.meta.env.VITE_VISITOR_PWD,
+    },
+  },
+};
diff --git a/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.vue b/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.vue
index b2577def83c9f629844012fe9abb8b4c9ccf4e2e..183f9c44e921badbb98777ea1e20f72015ef737d 100644
--- a/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.vue
+++ b/src/components/DatasetMultiStep/OcDatasetFormStep2/OcDatasetFormStep2.vue
@@ -2,15 +2,19 @@
   <Form
     class="flex flex-col gap-2"
     :validation-schema="validationSchema"
-    :initial-values="model"
+    :initial-values="{ catalog: model.catalog, graph: model.graph?.[0] }"
     @submit="submit"
+    v-slot="{ resetField }"
   >
     <Field name="catalog" v-slot="{ value, errorMessage, handleChange }">
       <OcField :metadata="datasetMetadata.catalog" for="catalog">
-        <OcCatalogAutocomplete
+        <OcCatalogSelect
           inputId="catalog"
           :model-value="value"
-          @update:model-value="handleChange"
+          :community="community"
+          :user-private-graph="userPrivateGraph"
+          :auth="auth"
+          @update:model-value="updateCatalogValue($event, handleChange, resetField)"
           :invalid="!!errorMessage"
           :multiple="false"
           required
@@ -19,6 +23,39 @@
       </OcField>
       <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
     </Field>
+    <Field name="visibility" v-slot="{ value, errorMessage, handleChange }">
+      <div class="flex gap-1 mb-2 items-center">
+        <label for="visibility" class="required">
+          {{ t('datasets.new.steps.2.access') }}
+        </label>
+        <OcFairBadge :letter="false" size="small" :badges="['f', 'r']" :popover="true" />
+      </div>
+      <Message severity="secondary" icon="fa fa-info" class="text-sm">
+        <p class="italic mb-2">{{ t('datasets.new.steps.2.accessHelp.1') }}</p>
+        <p class="mb-2">{{ t('datasets.new.steps.2.accessHelp.2') }}</p>
+        <p>{{ t('datasets.new.steps.2.accessHelp.3') }}</p>
+        <p class="mb-2">{{ t('datasets.new.steps.2.accessHelp.4') }}</p>
+        <p class="mb-2">{{ t('datasets.new.steps.2.accessHelp.5') }}</p>
+        <p class="mb-2">{{ t('datasets.new.steps.2.accessHelp.6') }}</p>
+      </Message>
+      <SelectButton
+        inputId="visibility"
+        :model-value="value"
+        :options="visibilityOptions"
+        optionLabel="key"
+        optionValue="graph"
+        optionDisabled="disabled"
+        @update:model-value="handleChange"
+        :invalid="!!errorMessage"
+        required
+      >
+        <template #option="slotProps">
+          <OcVisibilityIcon :visibility="slotProps.option.key" class="text-[0.6rem] -mr-1" />
+          {{ t('resourceVisibility.' + slotProps.option.key) }}
+        </template>
+      </SelectButton>
+      <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
+    </Field>
     <div class="flex justify-between pt-6">
       <Button
         :label="t('back')"
@@ -44,27 +81,82 @@ import { toTypedSchema } from '@vee-validate/yup'
 import * as yup from 'yup'
 import Button from 'primevue/button'
 import { useI18n } from 'vue-i18n'
-import type { OcCatalog, OcDataset } from '@/declarations'
-import OcCatalogAutocomplete from '@/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.vue'
+import type { Credentials, OcCatalogSummary, OcCommunity, OcDataset } from '@/declarations'
+import OcCatalogSelect from '@/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue'
 import Message from 'primevue/message'
 import { datasetMetadata } from '@/modelMetadata/dataset'
 import OcField from '@/components/FormInputs/OcField/OcField.vue'
+import { computed, ref, type PropType } from 'vue'
+import { useTranslateValue } from '@/composables/useTranslateValue'
+import { getVisibilityOptionsFor } from '@/helpers/resourceVisibility'
+import { SelectButton } from 'primevue'
+import OcVisibilityIcon from '@/components/OcVisibilityIcon/OcVisibilityIcon.vue'
+import OcFairBadge from '@/components/OcFairBadge/OcFairBadge.vue'
 
 const model = defineModel<Partial<OcDataset>>({ required: true })
 
+const props = defineProps({
+  community: {
+    type: Object as PropType<OcCommunity>,
+    required: true
+  },
+  userPrivateGraph: {
+    type: String,
+    required: true
+  },
+  auth: {
+    type: Object as PropType<Credentials>,
+    required: true
+  }
+})
 const emit = defineEmits(['back', 'next'])
 
 const { t } = useI18n()
+const { translateValue } = useTranslateValue()
+
+const validationSchema = computed(() =>
+  toTypedSchema(
+    yup.object({
+      catalog: yup
+        .mixed<OcCatalogSummary>()
+        .required()
+        .label(translateValue(datasetMetadata.catalog.label)),
+      visibility: yup
+        .string()
+        .matches(
+          new RegExp(
+            visibilityOptions.value
+              .filter((item) => !item.disabled)
+              .map((item) => item.key)
+              .join('|')
+          ),
+          'Choosen option is disabled'
+        )
+        .required()
+        .label(t('datasets.new.steps.2.access'))
+    })
+  )
+)
 
-const validationSchema = toTypedSchema(
-  yup.object({
-    catalog: yup.object<OcCatalog>().required().label(t('datasets.new.steps.2.catalog'))
-  })
+const visibilityOptions = ref(
+  getVisibilityOptionsFor(props.community, undefined, props.userPrivateGraph)
 )
 
+const updateCatalogValue = (
+  value: OcCatalogSummary | undefined,
+  handleChange: Function,
+  resetField: Function
+) => {
+  handleChange(value)
+  visibilityOptions.value = getVisibilityOptionsFor(props.community, value, props.userPrivateGraph)
+  resetField('visibility', undefined)
+}
+
 const submit = (values: GenericObject, ctx: SubmissionContext) => {
   model.value.catalog = values.catalog
 
+  model.value.graph = [values.visibility]
+
   const event = ctx.evt as SubmitEvent
   const action = ((event?.submitter as HTMLInputElement)?.value ?? 'next') as 'back' | 'next'
   emit(action)
diff --git a/src/components/FormInputs/OcAgentAutocomplete/OcAgentAutocomplete.vue b/src/components/FormInputs/OcAgentAutocomplete/OcAgentAutocomplete.vue
index 3678ccfc744fd2da8e0b1cea8fde211cf39406c1..8ecb6ba7947c6eb730dc36450f63613ea5872429 100644
--- a/src/components/FormInputs/OcAgentAutocomplete/OcAgentAutocomplete.vue
+++ b/src/components/FormInputs/OcAgentAutocomplete/OcAgentAutocomplete.vue
@@ -10,7 +10,8 @@
       :minLength="3"
       @complete="search($event.query)"
       :loading="loading"
-      :pt:pcInput:root:class="{ 'w-full': true, 'border-amber-200': !!errorMessage }"
+      :pt:pcInput:root:class="{ 'border-amber-200': !!errorMessage }"
+      fluid
     >
       <template #option="{ option }">
         <div class="flex items-center">
diff --git a/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.stories.ts b/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.stories.ts
deleted file mode 100644
index 57cdb57637f3c7445654a1c8ce794ad2be972b17..0000000000000000000000000000000000000000
--- a/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.stories.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/vue3';
-
-import OcCatalogAutocomplete from './OcCatalogAutocomplete.vue';
-
-const meta: Meta<typeof OcCatalogAutocomplete> = {
-  component: OcCatalogAutocomplete,
-};
-
-export default meta;
-type Story = StoryObj<typeof OcCatalogAutocomplete>;
-
-export const OrganizationAndPerson: Story = {
-  render: (args) => ({
-    components: { OcCatalogAutocomplete },
-    setup() {
-      return { args };
-    },
-    template: '<OcCatalogAutocomplete v-bind="args" />',
-  }),
-  args: {},
-};
diff --git a/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.vue b/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.vue
deleted file mode 100644
index a087a16d6c7b864854cbbcdd40d4a10914b8862c..0000000000000000000000000000000000000000
--- a/src/components/FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-<template>
-  <div class="flex flex-col w-full">
-    <AutoComplete
-      :inputId="$attrs.inputId"
-      v-model="model"
-      :suggestions="items"
-      :optionLabel="displayName"
-      forceSelection
-      :minLength="2"
-      @complete="search($event.query)"
-      :loading="loading"
-      :virtualScrollerOptions="{ itemSize: 30 }"
-      :pt:pcInput:root:class="{ 'w-full': true, 'border-amber-200': !!errorMessage }"
-    >
-      <template #option="{ option }">
-        <div class="flex items-center">
-          <span :class="icon" class="text-xs mr-1" />
-          {{ displayName(option) }}
-        </div>
-      </template>
-    </AutoComplete>
-    <Message class="mt-2" v-if="!!errorMessage" severity="warn">
-      {{ t('form.error.autocomplete') }}
-    </Message>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { useTranslateValue } from '@/composables/useTranslateValue'
-import type { OcCatalog } from '@/declarations'
-import { iconsDict } from '@/helpers/icons'
-import { queryCatalog } from '@/sparql/catalog'
-import AutoComplete from 'primevue/autocomplete'
-import Message from 'primevue/message'
-import { ref } from 'vue'
-import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
-const { translateValue } = useTranslateValue()
-
-defineProps({
-  multiple: {
-    type: Boolean,
-    required: false,
-    default: true
-  }
-})
-
-const model = defineModel<OcCatalog | undefined>()
-
-const { locale } = useI18n()
-const loading = ref<boolean>(false)
-const errorMessage = ref<string | null>(null)
-const items = ref<Array<OcCatalog>>([])
-
-const icon = iconsDict.catalog
-const displayName = (item: OcCatalog) => translateValue(item.title)
-
-async function search(query: string) {
-  loading.value = true
-  errorMessage.value = null
-  try {
-    items.value = await queryCatalog(query, locale.value)
-  } catch (e) {
-    items.value = []
-    errorMessage.value = (e as Error).message
-    console.error(e)
-  }
-
-  loading.value = false
-}
-</script>
diff --git a/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.stories.ts b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..52c0ca34cc05a79c25fb7e1fbf0fe65faa482bc2
--- /dev/null
+++ b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.stories.ts
@@ -0,0 +1,28 @@
+import type { Meta, StoryObj } from '@storybook/vue3';
+
+import OcCatalogSelect from './OcCatalogSelect.vue';
+import { communityExample1 } from '@/assets/communityExample1';
+
+const meta: Meta<typeof OcCatalogSelect> = {
+  component: OcCatalogSelect,
+};
+
+export default meta;
+type Story = StoryObj<typeof OcCatalogSelect>;
+
+export const Default: Story = {
+  render: (args) => ({
+    components: { OcCatalogSelect },
+    setup() {
+      return { args };
+    },
+    template: '<OcCatalogSelect v-bind="args" />',
+  }),
+  args: {
+    community: communityExample1,
+    auth: {
+      email: import.meta.env.VITE_VISITOR_USER,
+      password: import.meta.env.VITE_VISITOR_PWD,
+    }
+  },
+};
diff --git a/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue
new file mode 100644
index 0000000000000000000000000000000000000000..fcb1829d2f4284c601b4157b94142902be4cc37b
--- /dev/null
+++ b/src/components/FormInputs/OcCatalogSelect/OcCatalogSelect.vue
@@ -0,0 +1,187 @@
+<template>
+  <div class="flex flex-col w-full">
+    <TreeSelect
+      v-model="internalModel"
+      name="node"
+      @node-expand="onNodeExpand"
+      :loading="loading"
+      :options="nodes"
+      :loading-mode="loading ? 'mask' : 'icon'"
+      :pt:pcInput:root:class="{ 'w-full': true, 'border-amber-200': !!errorMessage }"
+    >
+      <template #option="{ node }">
+        <span class="p-tree-node-icon text-[0.8rem]">
+          <i :class="iconsDict.catalog" class="fa-lg fa-fw" />
+          <OcVisibilityIcon
+            v-if="node.visibility !== 'public'"
+            :visibility="node.visibility"
+            class="text-[0.6rem] pt-2 -ml-3 mr-0.5"
+          />
+        </span>
+        {{ node.label }}
+      </template>
+    </TreeSelect>
+    <Message class="mt-2" v-if="!!errorMessage" severity="warn">
+      {{ t('form.error.autocomplete') }}
+    </Message>
+  </div>
+</template>
+
+<script setup lang="ts">
+import OcVisibilityIcon from '@/components/OcVisibilityIcon/OcVisibilityIcon.vue'
+import { useTranslateValue } from '@/composables/useTranslateValue'
+import type { Credentials, OcCatalogSummary, OcCommunity } from '@/declarations'
+import { iconsDict } from '@/helpers/icons'
+import {
+  getCatalogSummaryFromParentUri,
+  getCatalogSummaryFromChildUri,
+  getCatalogSummaryFromUri
+} from '@/sparql/catalog'
+import Message from 'primevue/message'
+import type { TreeNode } from 'primevue/treenode'
+import TreeSelect from 'primevue/treeselect'
+import { getResourceVisibility } from '@/helpers/resourceVisibility'
+import { onMounted, ref, watch, type PropType } from 'vue'
+import { useI18n } from 'vue-i18n'
+import { homeNodeUri } from '@/stores/tree'
+
+const { t } = useI18n()
+const { translateValue } = useTranslateValue()
+
+const props = defineProps({
+  community: {
+    type: Object as PropType<OcCommunity>,
+    required: true
+  },
+  userPrivateGraph: {
+    type: String,
+    required: false
+  },
+  auth: {
+    type: Object as PropType<Credentials | undefined>,
+    required: false
+  }
+})
+
+const model = defineModel<OcCatalogSummary | undefined>()
+const internalModel = ref<{ [k: string]: boolean } | undefined>(undefined)
+
+watch(internalModel, (internalModel) => {
+  if (internalModel === undefined) {
+    model.value = undefined
+  }
+  const catalogUri = Object.keys(internalModel as { [k: string]: boolean })[0]
+  model.value = internalModel ? catalogList.value[catalogUri] : undefined
+})
+
+const errorMessage = ref<string | null>(null)
+const loading = ref(true)
+
+const nodes = ref<TreeNode[]>([])
+const catalogList = ref<Record<string, OcCatalogSummary>>({})
+
+onMounted(async () => {
+  loading.value = true
+  // Initalize tree with given value
+  if (model.value !== undefined) {
+    const givenCatalog = await getCatalogSummaryFromUri(model.value['@id'], props.auth)
+
+    if (givenCatalog) {
+      // We go from the pre-selected catalog to a catalog in our list.
+      catalogList.value[givenCatalog['@id']] = givenCatalog
+      let givenCatalogBranch: TreeNode = {
+        key: givenCatalog['@id'],
+        label: translateValue(givenCatalog.title),
+        leaf: !givenCatalog.catalog?.length,
+        visibility: getResourceVisibility(props.community, givenCatalog, props.userPrivateGraph)
+      }
+      let currentCatalogUri: string | undefined = model.value['@id']
+      do {
+        const catalogs = await getCatalogSummaryFromChildUri(currentCatalogUri, props.auth)
+        if (catalogs && catalogs.length) {
+          // We arbitrary take the first catalog
+          const catalog = catalogs[0]
+          givenCatalogBranch = {
+            key: catalog['@id'],
+            label: translateValue(catalog.title),
+            leaf: !catalog.catalog?.length,
+            visibility: getResourceVisibility(props.community, catalog, props.userPrivateGraph),
+            children: [{ ...givenCatalogBranch }]
+          }
+
+          catalogList.value[catalog['@id']] = catalog
+          await onNodeExpand(givenCatalogBranch, true)
+          currentCatalogUri = catalog['@id']
+        } else {
+          currentCatalogUri = undefined
+        }
+      } while (currentCatalogUri)
+
+      nodes.value.push(givenCatalogBranch)
+      internalModel.value = { [model.value['@id']]: true }
+    } else {
+      errorMessage.value = "Given catalog can't be found !"
+    }
+  } else {
+    try {
+      for (const catalog of await getCatalogSummaryFromParentUri(homeNodeUri, props.auth)) {
+        if (!Object.keys(catalogList.value).includes(catalog['@id'])) {
+          const node = {
+            key: catalog['@id'],
+            label: translateValue(catalog.title),
+            leaf: !catalog.catalog?.length,
+            visibility: getResourceVisibility(props.community, catalog, props.userPrivateGraph)
+          }
+          nodes.value.push(node)
+          catalogList.value[catalog['@id']] = catalog
+
+          if (catalog.catalog?.length) {
+            onNodeExpand(node)
+          }
+        }
+      }
+    } catch (e) {
+      console.error(e)
+      errorMessage.value = (e as Error).message
+    }
+  }
+
+  loading.value = false
+})
+
+const onNodeExpand = async (node: TreeNode, force: boolean = false) => {
+  // No child to get
+  if (node.leaf) {
+    return
+  }
+  // Children already loaded
+  if (!force && node.children?.length) {
+    return
+  }
+
+  node.loading = true
+  const nodeCatalog = catalogList.value[node.key]
+  try {
+    for (const catalog of await getCatalogSummaryFromParentUri(nodeCatalog['@id'], props.auth)) {
+      const child = {
+        key: catalog['@id'],
+        label: translateValue(catalog.title),
+        leaf: !catalog.catalog?.length,
+        visibility: getResourceVisibility(props.community, catalog, props.userPrivateGraph)
+      }
+      if (node.children) {
+        if (!node.children.find((child) => child.key === catalog['@id'])) {
+          node.children.push(child)
+        }
+      } else {
+        node.children = [child]
+      }
+      catalogList.value[catalog['@id']] = catalog
+    }
+  } catch (e) {
+    console.error(e)
+    errorMessage.value = (e as Error).message
+  }
+  node.loading = false
+}
+</script>
diff --git a/src/components/FormInputs/OcConceptAutocomplete/OcConceptAutocomplete.vue b/src/components/FormInputs/OcConceptAutocomplete/OcConceptAutocomplete.vue
index 82e9a6b9d811a50675cb8ff2d7735714ff7ab8ac..e3e13189cc1287581366322afb0fe3f6b2c8b971 100644
--- a/src/components/FormInputs/OcConceptAutocomplete/OcConceptAutocomplete.vue
+++ b/src/components/FormInputs/OcConceptAutocomplete/OcConceptAutocomplete.vue
@@ -12,7 +12,8 @@
         :minLength="1"
         @complete="search($event.query)"
         :loading="loading"
-        :pt:pcInput:root:class="{ 'w-full': true, 'border-amber-200': !!errorMessage }"
+        :pt:pcInput:root:class="{ 'border-amber-200': !!errorMessage }"
+        fluid
         class="w-full"
       />
       <Button
@@ -105,7 +106,7 @@ async function search(query: string) {
 }
 
 watch(model, () => {
-  if(!props.multiple && isBrowserVisible.value){
+  if (!props.multiple && isBrowserVisible.value) {
     isBrowserVisible.value = false
   }
 })
diff --git a/src/components/FormInputs/OcMultilingualField/OcMultilingualField.vue b/src/components/FormInputs/OcMultilingualField/OcMultilingualField.vue
index 7317a87e04d2bbfcdd23b1c6bc8ff7f606ffb26f..ed9484604f8a86ed5601b7bbe5b31ebe7c372d76 100644
--- a/src/components/FormInputs/OcMultilingualField/OcMultilingualField.vue
+++ b/src/components/FormInputs/OcMultilingualField/OcMultilingualField.vue
@@ -14,7 +14,7 @@
         <div class="flex flex-col gap-1 w-full">
           <InputGroup class="w-56">
             <InputGroupAddon>
-              <i class="fa-solid fa-globe"></i>
+              <i class="fa-solid fa-globe mx-1"></i>
             </InputGroupAddon>
             <Select
               :modelValue="values[key].locale"
diff --git a/src/components/OcCardCommunity/OcCardCommunity.stories.ts b/src/components/OcCardCommunity/OcCardCommunity.stories.ts
index ac76cbd1ca68eafa559c18ece15eaaf23a78be48..f0dd966cc02ffd2a43cdddb8bd3d86257e00eaae 100644
--- a/src/components/OcCardCommunity/OcCardCommunity.stories.ts
+++ b/src/components/OcCardCommunity/OcCardCommunity.stories.ts
@@ -1,6 +1,7 @@
 import type { Meta, StoryObj } from '@storybook/vue3';
 
 import OcCardCommunity from './OcCardCommunity.vue';
+import { communityExample1 } from '@/assets/communityExample1';
 
 const meta: Meta<typeof OcCardCommunity> = {
   component: OcCardCommunity,
@@ -18,20 +19,6 @@ export const Primary: Story = {
     template: '<OcCardCommunity v-bind="args" />',
   }),
   args: {
-    community: {
-      description: {
-        fr: "Lauréat de la deuxième vague de l'appel à projet Laboratoire d'Excellence (LabEx) dans le cadre du programme « Investissements d'avenir », le LabEx DRIIHM, Dispositif de Recherche Interdisciplinaire sur les Interactions Hommes-Milieux, regroupe à ce jour 13 Observatoires Hommes-Milieux, outils d'observation de socio-écosystèmes impactés par un événement d'origine anthropique. Créés par le CNRS-INEE en 2007, ils sont répartis en France métropolitaine, en outre-mer et à l’étranger.",
-        en: "Laureate of the Laboratory for Excellence project (LabEx) in the program « Investment in the future », the DRIIHM LabEx, Device for Interdisciplinary Research on human-environments Interactions, aggregate 13 human-environments observatories (OHM in french), tools for observing socio-ecosystems impacted by anthropic events. Created by CNRS-INEE in 2007, they are located in metropolitan France, overseas France and abroad."
-      },
-      identifier: "189088ec-baa9-4397-8c6f-eefde9a3790c",
-      title: {
-        fr: "Communauté du LabEx DRIIHM",
-        en: "DRIIHM Community"
-      },
-      logo: "https://www.driihm.fr/images/images/logos_png/logo_DRIIHM_r%C3%A9duit.png",
-      name: "driihm",
-      isSpaceOf: "https://www.irit.fr/opencommon/agents/organization/9a20f121-c64e-4049-93a7-4bedbe819fd6",
-      color: 'linen'
-    }
+    community: communityExample1
   },
 };
\ No newline at end of file
diff --git a/src/components/OcCatalogForm/OcCatalogForm.stories.ts b/src/components/OcCatalogForm/OcCatalogForm.stories.ts
index ac76118d9e754628437f69221a0c00f26f683d6c..f6b585d371c0bfc23d5d2abcb1de67c198bb0a74 100644
--- a/src/components/OcCatalogForm/OcCatalogForm.stories.ts
+++ b/src/components/OcCatalogForm/OcCatalogForm.stories.ts
@@ -1,6 +1,7 @@
 import type { Meta, StoryObj } from '@storybook/vue3';
 
 import OcCatalogForm from './OcCatalogForm.vue';
+import { communityExample1 } from '@/assets/communityExample1';
 
 const meta: Meta<typeof OcCatalogForm> = {
   component: OcCatalogForm,
@@ -19,6 +20,12 @@ export const Default: Story = {
   }),
   args: {
     modelValue: {},
+    community: communityExample1,
+    userPrivateGraph: 'private-graph',
+    auth: {
+      email: import.meta.env.VITE_VISITOR_USER,
+      password: import.meta.env.VITE_VISITOR_PWD,
+    }
   },
 };
 
@@ -32,6 +39,12 @@ export const CustomLabels: Story = {
   }),
   args: {
     modelValue: {},
+    community: communityExample1,
+    userPrivateGraph: 'private-graph',
+    auth: {
+      email: import.meta.env.VITE_VISITOR_USER,
+      password: import.meta.env.VITE_VISITOR_PWD,
+    },
     saveLabel: 'Next',
     cancelLabel: 'Exit',
   },
@@ -47,6 +60,12 @@ export const WithoutCancel: Story = {
   }),
   args: {
     modelValue: {},
+    community: communityExample1,
+    userPrivateGraph: 'private-graph',
+    auth: {
+      email: import.meta.env.VITE_VISITOR_USER,
+      password: import.meta.env.VITE_VISITOR_PWD,
+    },
     cancelButton: false,
   },
 };
diff --git a/src/components/OcCatalogForm/OcCatalogForm.vue b/src/components/OcCatalogForm/OcCatalogForm.vue
index b90021523f61fc0b1ebca5fe752f368b3290ad0d..6528b670fa93d03f5b936236204da3ea023dc3ce 100644
--- a/src/components/OcCatalogForm/OcCatalogForm.vue
+++ b/src/components/OcCatalogForm/OcCatalogForm.vue
@@ -7,10 +7,12 @@
   >
     <Field name="parentCatalog" v-slot="{ value, errorMessage, handleChange }">
       <OcField for="parentCatalog" :metadata="catalogMetadata.parentCatalog">
-        <OcCatalogAutocomplete
+        <OcCatalogSelect
           inputId="parentCatalog"
           :model-value="value"
           @update:model-value="handleChange"
+          :community="community"
+          :auth="auth"
           :invalid="!!errorMessage"
           :multiple="false"
           required
@@ -71,7 +73,7 @@
       </OcField>
       <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
     </Field>
-    <Field name="issued" v-slot="{ value, errorMessage, handleChange }" >
+    <Field name="issued" v-slot="{ value, errorMessage, handleChange }">
       <OcField for="issued" :metadata="catalogMetadata.issued">
         <DatePicker
           id="issued"
@@ -84,7 +86,7 @@
       </OcField>
       <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
     </Field>
-    <Field name="theme" v-slot="{ value, handleChange, errorMessage }" >
+    <Field name="theme" v-slot="{ value, handleChange, errorMessage }">
       <OcField for="theme" :metadata="catalogMetadata.theme">
         <OcConceptAutocomplete
           inputId="theme"
@@ -99,7 +101,7 @@
       </OcField>
       <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
     </Field>
-    <Field name="temporal" v-slot="{ value, errorMessage, handleChange }" >
+    <Field name="temporal" v-slot="{ value, errorMessage, handleChange }">
       <OcField for="temporal" :metadata="catalogMetadata.temporal">
         <OcMultipleField
           id="temporal"
@@ -117,7 +119,7 @@
       </OcField>
       <Message v-if="errorMessage" severity="error">{{ errorMessage }}</Message>
     </Field>
-    <Field name="spatial" v-slot="{ value, errorMessage, handleChange }" >
+    <Field name="spatial" v-slot="{ value, errorMessage, handleChange }">
       <OcField for="spatial" :metadata="catalogMetadata.spatial">
         <OcConceptAutocomplete
           inputId="spatial"
@@ -162,7 +164,10 @@ import type {
   OcPerson,
   OcConcept,
   LocalizedProperty,
-  OcCatalog
+  OcCatalog,
+  OcCommunity,
+  Credentials,
+  OcCatalogSummary
 } from '@/declarations'
 import Button from 'primevue/button'
 import { useI18n } from 'vue-i18n'
@@ -173,17 +178,30 @@ import Message from 'primevue/message'
 import OcField from '@/components/FormInputs/OcField/OcField.vue'
 import OcAgentAutocomplete from '@/components/FormInputs/OcAgentAutocomplete/OcAgentAutocomplete.vue'
 import OcConceptAutocomplete from '@/components/FormInputs/OcConceptAutocomplete/OcConceptAutocomplete.vue'
-import OcCatalogAutocomplete from '../FormInputs/OcCatalogAutocomplete/OcCatalogAutocomplete.vue'
+import OcCatalogSelect from '../FormInputs/OcCatalogSelect/OcCatalogSelect.vue'
 import { useTranslateValue } from '@/composables/useTranslateValue'
 import { catalogMetadata } from '@/modelMetadata/catalog'
 import { toTypedSchema } from '@vee-validate/yup'
 import OcMultilingualField from '../FormInputs/OcMultilingualField/OcMultilingualField.vue'
 import OcMultipleField from '../FormInputs/OcMultipleField/OcMultipleField.vue'
+import type { PropType } from 'vue'
 
 const { t } = useI18n()
 const { translateValue } = useTranslateValue()
 
 defineProps({
+  community: {
+    type: Object as PropType<OcCommunity>,
+    required: true
+  },
+  userPrivateGraph: {
+    type: String,
+    required: false
+  },
+  auth: {
+    type: Object as PropType<Credentials | undefined>,
+    required: false
+  },
   saveLabel: {
     type: [String, null],
     default: null
@@ -208,7 +226,7 @@ const emit = defineEmits<{
 const validationSchema = toTypedSchema(
   yup.object({
     parentCatalog: yup
-      .object<OcCatalog>()
+      .object<OcCatalogSummary>()
       .required()
       .label(translateValue(catalogMetadata.parentCatalog.label)),
     title: yup
diff --git a/src/declarations.ts b/src/declarations.ts
index 1a54d6b0e146df711fffdb0d4dd89f0b9c413c12..ec5bd930e6fa65d239b0b4128e4b3fcd2f99e2fc 100644
--- a/src/declarations.ts
+++ b/src/declarations.ts
@@ -1,5 +1,12 @@
 import type { ContextDefinition } from 'jsonld'
 import type { RouteLocationAsRelativeGeneric } from 'vue-router'
+import {
+  roleVisitor,
+  roleCommunityMember,
+  roleCommunityManager,
+  rolePlatformManager,
+  roleCatalogManager
+} from '@/helpers/roles'
 
 export type Credentials = {
   email: string
@@ -25,6 +32,7 @@ export type OcCommunity = {
   logo: undefined | string
   color: undefined | string
   isSpaceOf: undefined | string
+  catalog: string[]
 }
 
 export type OcAdmsIdentifier = {
@@ -51,10 +59,12 @@ export type OcCatalog = OcResource & {
   issued?: Date
   temporal?: [Date, Date][]
   spatial?: Array<OcConcept | OcGeometry>
-  parentCatalog?: OcCatalog
+  parentCatalog?: OcCatalog | OcCatalogSummary
 }
 
-export type OcCatalogSummary = OcResource
+export type OcCatalogSummary = OcResource & {
+  catalog?: string[]
+}
 
 export type OcDataset = OcResource & {
   otherIdentifier?: OcAdmsIdentifier[]
@@ -147,7 +157,7 @@ export type OcConceptScheme = {
 
 export type OcGeometry = {
   '@id'?: string,
-  geometry: Array<{'@type': string, '@value': string}>
+  geometry: Array<{ '@type': string, '@value': string }>
 }
 
 export type OcOrganization = {
@@ -181,7 +191,7 @@ export type OcMemberInfos = {
 }
 
 export type OcMembership = {
-  role: string
+  role: OcRole
   organization: string
 }
 
@@ -231,3 +241,5 @@ export type OcLocale = {
   prefLabel: LocalizedProperty<string>
   code: string
 }
+
+export type OcRole = typeof roleVisitor | typeof roleCommunityMember | typeof roleCommunityManager | typeof rolePlatformManager | typeof roleCatalogManager
\ No newline at end of file
diff --git a/src/helpers/resourceVisibility.ts b/src/helpers/resourceVisibility.ts
index 75ba81fbce2ec421065ee363466848c338098bee..b0ff3cd980cea44a642e6c858d6b8c63607cc508 100644
--- a/src/helpers/resourceVisibility.ts
+++ b/src/helpers/resourceVisibility.ts
@@ -1,5 +1,13 @@
 import type { OcCommunity, OcResource, Visibility } from "@/declarations";
 
+function getCommunityPublicGraph(community?: OcCommunity, legacy: boolean = false) {
+  return `https://www.irit.fr/opencommon/${legacy ? 'spaces' : 'communities'}/${community?.identifier}/publicResources`
+}
+
+function getCommunityGraph(community?: OcCommunity, legacy: boolean = false) {
+  return `https://www.irit.fr/opencommon/${legacy ? 'spaces' : 'communities'}/${community?.identifier}/communityResources`
+}
+
 export function getResourceVisibility(
   community?: OcCommunity,
   resource?: OcResource,
@@ -8,13 +16,13 @@ export function getResourceVisibility(
   const graph = resource?.graph ?? []
 
   if (
-    graph.includes(`https://www.irit.fr/opencommon/communities/${community?.identifier}/publicResources`)
-    || graph.includes(`https://www.irit.fr/opencommon/spaces/${community?.identifier}/publicResources`)
+    graph.includes(getCommunityPublicGraph(community))
+    || graph.includes(getCommunityPublicGraph(community, true))
   ) {
     return 'public'
   } else if (
-    graph.includes(`https://www.irit.fr/opencommon/communities/${community?.identifier}/communityResources`)
-    || graph.includes(`https://www.irit.fr/opencommon/spaces/${community?.identifier}/communityResources`)
+    graph.includes(getCommunityGraph(community))
+    || graph.includes(getCommunityGraph(community, true))
   ) {
     return 'community'
   } else if (userPrivateGraph && graph.includes(userPrivateGraph)) {
@@ -24,3 +32,35 @@ export function getResourceVisibility(
     return 'protected'
   }
 }
+
+export function getVisibilityOptionsFor(community?: OcCommunity, resource?: OcResource, userPrivateGraph?: string) {
+  const options = {
+    public: { key: 'public', graph: getCommunityPublicGraph(community), disabled: false },
+    community: { key: 'community', graph: getCommunityGraph(community), disabled: false },
+    private: { key: 'private', graph: userPrivateGraph, disabled: false },
+  }
+
+  if (resource === undefined) {
+    options.public.disabled = true
+    options.community.disabled = true
+    options.private.disabled = true
+
+    return Object.values(options)
+  }
+
+  switch (getResourceVisibility(community, resource, userPrivateGraph)) {
+    case 'public':
+      // Nothing to do, all options are available
+      break
+    case 'community':
+    case 'protected':
+      options.public.disabled = true
+      break
+    case 'private':
+      options.public.disabled = true
+      options.community.disabled = true
+      break
+  }
+
+  return Object.values(options)
+}
diff --git a/src/helpers/roles.ts b/src/helpers/roles.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2ae5a68486f658e9914ef15aca0ef80a83ca1c45
--- /dev/null
+++ b/src/helpers/roles.ts
@@ -0,0 +1,13 @@
+export const roleVisitor = 'https://www.irit.fr/opencommon/terms/Visitor'
+
+export const roleCommunityMember = 'https://www.irit.fr/opencommon/terms/communityMember'
+/** @deprecated use roleCommunityMember instead */
+export const roleSpaceMember = 'https://www.irit.fr/opencommon/terms/SpaceMember'
+
+export const roleCommunityManager = 'https://www.irit.fr/opencommon/terms/communityManager'
+/** @deprecated use roleCommunityManager instead */
+export const roleSpaceManager = 'https://www.irit.fr/opencommon/terms/SpaceManager'
+
+export const rolePlatformManager = 'https://www.irit.fr/opencommon/terms/PlatformManager'
+
+export const roleCatalogManager = 'https://www.irit.fr/opencommon/terms/CatalogManager'
\ No newline at end of file
diff --git a/src/locales/en.ts b/src/locales/en.ts
index 8e03bde9f15286cf2b379c37e4585e7563aeb99d..4e2e40d5bb77a5b0711bf5063fe007dd4f23539d 100644
--- a/src/locales/en.ts
+++ b/src/locales/en.ts
@@ -172,10 +172,18 @@ export default {
         2: {
           label: 'Select a catalogue and manage metadata access',
           description: {
-            1: "Select a location to store the dataset's metadata..",
+            1: "Select a location to store the dataset's metadata.",
             2: 'Select the level of metadata access in the chosen catalogue.'
           },
-          catalog: 'Catalog'
+          access: 'Access rights to the resource',
+          accessHelp: {
+            1: "Access rights determine who can view the resource.",
+            2: "Depending on your role within the community and the catalog in which you wish to insert the resource, the available options may vary.",
+            3: "If you want your resource to be public, but the option is not available, it's because you don't have sufficient rights to do so.",
+            4: "In this case, create your resource as a community resource. Once created, you'll be able to ask a moderator to publish it.",
+            5: "A community resource is only visible to members of the community.",
+            6: "You can choose to keep your resource private, in which case it will only be visible to you. It will then be possible to modify this access from the dashboard."
+          }
         },
         3: {
           label: 'Add Distribution(s)',
diff --git a/src/locales/fr.ts b/src/locales/fr.ts
index ff16956381d025f25e0a9449ded7293be1915840..4788c5c1adf09ccd6b6bd136cb63630c6adc42ca 100644
--- a/src/locales/fr.ts
+++ b/src/locales/fr.ts
@@ -176,7 +176,15 @@ export default {
             1: 'Sélectionner un endroit où stocker les métadonnées du jeu de données.',
             2: "Sélectionner le niveau d'accès aux métadonnées dans le catalogue choisi."
           },
-          catalog: 'Catalogue'
+          access: 'Droit d\'accès de la ressource',
+          accessHelp: {
+            1: "Les droits d'accès déterminent qui aura le droit de voir la ressource.",
+            2: "En fonction de votre rôle au sein de la communauté et du catalogue dans lequel vous souhaitez insérer la ressource, les options disponibles peuvent variées.",
+            3: "Si vous souhaitez qui votre resource soit publique mais que l'option n'est pas disponible, c'est que vous n'avez pas les droits suffisants pour le faire.",
+            4: "Dans ce cas, créer votre en tant que resource communautaire, une fois votre resource créée, vous aurez la possibilité de demander sa publication à un modérateur.",
+            5: "Une resource communautaire n'est visible que des membre de la communauté.",
+            6: "Vous pouvez choisir de garder votre ressource privée, dans ce cas, elle ne sera visible que par vous. Il sera ensuite possible de modifier accès à partir du tableau de bord."
+          }
         },
         3: {
           label: 'Ajouter une ou des distributions',
diff --git a/src/pages/community/[community].catalog/[[identifier]].new.vue b/src/pages/community/[community].catalog/[[identifier]].new.vue
index 3705cb8b57e22bc0271fae1f17eaac3a8025113b..bcb39ae57dd1a688caae6769720a49bb812565a1 100644
--- a/src/pages/community/[community].catalog/[[identifier]].new.vue
+++ b/src/pages/community/[community].catalog/[[identifier]].new.vue
@@ -11,6 +11,9 @@
       </h1>
       <OcCatalogForm
         :modelValue="catalog"
+        :community="community"
+        :user-private-graph="accountStore.infos?.hasPrivateGraph"
+        :auth="accountStore.auth"
         @save="send"
         @cancel="router.back()"
       />
@@ -95,7 +98,7 @@ const catalog = ref<OcCatalog>({
   '@type': [''],
   title: {},
   description: {},
-  parentCatalog: parentCatalog.value,
+  parentCatalog: parentCatalog.value
 })
 
 const sending = ref(false)
@@ -133,7 +136,6 @@ const send = async () => {
       accountStore.auth
     )
 
-
     sent.value = true
   } catch (e) {
     console.error(e)
@@ -157,4 +159,4 @@ const breadcrumbItems = computed<OcBreadcrumbItem[]>(() => [
     type: 'new'
   }
 ])
-</script>
\ No newline at end of file
+</script>
diff --git a/src/pages/community/[community].dataset/new.vue b/src/pages/community/[community].dataset/new.vue
index 1e4374cd78f24d8c75416c76200f92ae1385dd01..aa6e83d85358ee128c66dcb13c67092d08894edc 100644
--- a/src/pages/community/[community].dataset/new.vue
+++ b/src/pages/community/[community].dataset/new.vue
@@ -219,7 +219,11 @@ const steps = computed(() => {
       label: 'datasets.new.steps.2.label',
       description: ['datasets.new.steps.2.description.1', 'datasets.new.steps.2.description.2'],
       component: OcDatasetFormStep2,
-      props: {},
+      props: {
+        community: community.value,
+        userPrivateGraph: accountStore.infos?.hasPrivateGraph,
+        auth: accountStore.auth
+      },
       back: (activateCallback: Function) => activateCallback('1'),
       next: (activateCallback: Function) => activateCallback('3')
     },
diff --git a/src/pages/community/[community]/dataset.[identifier].edit.vue b/src/pages/community/[community]/dataset.[identifier].edit.vue
index 5545c4c3488d263405dcb4ecd755aac0d93ae0c6..44860552df5c532d6e89013656a141addde5ae24 100644
--- a/src/pages/community/[community]/dataset.[identifier].edit.vue
+++ b/src/pages/community/[community]/dataset.[identifier].edit.vue
@@ -124,13 +124,7 @@ const save = async () => {
 
   try {
     // Update dataset
-    dataset.value = await updateDataset(
-      dataset.value,
-      // @todo How to get dataset actual graph?
-      accountStore.infos.hasPrivateGraph,
-      accountStore.profile,
-      accountStore.auth
-    )
+    dataset.value = await updateDataset(dataset.value, accountStore.profile, accountStore.auth)
 
     saved.value = true
   } catch (e) {
diff --git a/src/sparql/catalog.ts b/src/sparql/catalog.ts
index 2f97db5c4213f8eff51ae871cb87152eac2a98c6..0f1ae00616a6794e05b7317e9019205e84178e2b 100644
--- a/src/sparql/catalog.ts
+++ b/src/sparql/catalog.ts
@@ -27,8 +27,8 @@ export const queryCatalog = async (query: string, locale: string, auth?: Credent
   )
 }
 
-export const getCatalogSummary = async (identifier:string, auth?: Credentials): Promise<OcCatalogSummary | null> => {
-  const result = await executeSparqlConstruct<OcCatalog>(
+export const getCatalogSummary = async (identifier: string, auth?: Credentials) => {
+  const result = await executeSparqlConstruct<OcCatalogSummary>(
     `
     CONSTRUCT {
       ?catalog dct:title ?title;
@@ -41,6 +41,7 @@ export const getCatalogSummary = async (identifier:string, auth?: Credentials):
         rdf:type
         dct:title
         dct:description
+        dcat:catalog
       }
       ?catalog a dcat:Catalog;
                ?p ?o.
@@ -52,17 +53,120 @@ export const getCatalogSummary = async (identifier:string, auth?: Credentials):
     `,
     {
       auth: auth,
-      context: resourceContext
+      context: {
+        ...resourceContext,
+        catalog: {
+          "@id": "http://www.w3.org/ns/dcat#catalog",
+          "@type": "@id",
+          "@container": "@set"
+        }
+      }
+    }
+  )
+  if (result.length) {
+    return result[0]
+  } else {
+    console.warn('Catalog with identifier "' + identifier + '" not found')
+    return null
+  }
+}
+
+export const getCatalogSummaryFromUri = async (uri: string, auth?: Credentials) => {
+  const result = await executeSparqlConstruct<OcCatalogSummary>(
+    `
+    CONSTRUCT {
+      <${uri}> ?p ?o;
+               oct:graph ?g.
+    }
+    WHERE {
+      <${uri}> a dcat:Catalog;
+               ?p ?o.
+      GRAPH ?g {
+        <${uri}> dct:identifier ?identifier
+      }
+    }
+    `,
+    {
+      auth: auth,
+      context: {
+        ...resourceContext,
+        catalog: {
+          "@id": "http://www.w3.org/ns/dcat#catalog",
+          "@type": "@id",
+          "@container": "@set"
+        }
+      }
     }
   )
-  if (result.length){
+
+  if (result.length) {
     return result[0]
   } else {
-    console.warn('Catalog with identifier "'+identifier+'" not found')
+    console.warn('Catalog with uri "' + uri + '" not found')
     return null
   }
 }
 
+export const getCatalogSummaryFromParentUri = async (uri: string, auth?: Credentials) => {
+  return await executeSparqlConstruct<OcCatalogSummary>(
+    `
+    CONSTRUCT {
+      ?node ?p ?o;
+               oct:graph ?g.
+    }
+    WHERE {
+      <${uri}> a dcat:Catalog;
+               dcat:catalog ?node.
+      ?node ?p ?o.
+      GRAPH ?g {
+        ?node dct:identifier ?identifier
+      }
+    }
+    `,
+    {
+      auth: auth,
+      context: {
+        ...resourceContext,
+        catalog: {
+          "@id": "http://www.w3.org/ns/dcat#catalog",
+          "@type": "@id",
+          "@container": "@set"
+        }
+      }
+    }
+  )
+}
+
+export const getCatalogSummaryFromChildUri = async (uri: string, auth?: Credentials) => {
+  return await executeSparqlConstruct<OcCatalogSummary>(
+    `
+    CONSTRUCT {
+      ?node ?p ?o;
+               oct:graph ?g.
+    }
+    WHERE {
+      ?node a dcat:Catalog;
+               dcat:catalog <${uri}>.
+      ?node ?p ?o.
+      GRAPH ?g {
+        ?node dct:identifier ?identifier
+      }
+    }
+    `,
+    {
+      auth: auth,
+      context: {
+        ...resourceContext,
+        catalog: {
+          "@id": "http://www.w3.org/ns/dcat#catalog",
+          "@type": "@id",
+          "@container": "@set"
+        }
+      }
+    }
+  )
+}
+
 export async function insertCatalog(
   catalog: OcCatalog,
   graph: string,
diff --git a/src/sparql/communities.ts b/src/sparql/communities.ts
index f049af2c14f07a15c29dd6a6e43cc53a172a3880..a2185979b701aa762d4e9ba699d0a9281942a374 100644
--- a/src/sparql/communities.ts
+++ b/src/sparql/communities.ts
@@ -70,7 +70,3 @@ export function insertCommunityAccessRequest(communityUri: string, userLoginID:
     { auth: auth }
   )
 }
-
-export function buildCommunityGraphUri(community: OcCommunity): string {
-  return `https://www.irit.fr/opencommon/spaces/${community.identifier}`
-}
diff --git a/src/sparql/datasets.ts b/src/sparql/datasets.ts
index 2b2ef0af00d340a861b40838a78366993d04c81f..fecf89f3874340b47d688ffb9d10814c49c4c7c6 100644
--- a/src/sparql/datasets.ts
+++ b/src/sparql/datasets.ts
@@ -1,14 +1,13 @@
-import {
-  type OcResource,
-  type Credentials,
-  type OcCatalog,
-  type OcDataset,
-  type OcPerson,
-  type OcConcept,
-  type OcOrganization,
-  type OcDatasetSummary,
-  type OcAdmsIdentifier,
-  type OcGeometry
+import type {
+  OcResource,
+  Credentials,
+  OcDataset,
+  OcPerson,
+  OcConcept,
+  OcOrganization,
+  OcDatasetSummary,
+  OcAdmsIdentifier,
+  OcGeometry
 } from '@/declarations'
 import {
   defaultLocalizedPropFormatter,
@@ -24,17 +23,22 @@ import { resourceContext } from './resource'
 
 export async function insertDataset(
   dataset: OcDataset,
-  graph: string,
-  catalog: OcCatalog,
   profile: OcPerson,
   auth?: Credentials
 ) {
   dataset.identifier ||= crypto.randomUUID()
   dataset['@id'] ||= `${import.meta.env.VITE_OC_URI_BASE_URL}/datasets/${dataset.identifier}`
 
+  if (!dataset.graph) {
+    throw Error('Dataset has no graph!')
+  }
+  if (!dataset.catalog) {
+    throw Error('Dataset has no catalog!')
+  }
+
   let insertQuery = `
-    INSERT INTO <${graph}> {
-      <${catalog['@id']}> dcat:dataset <${dataset["@id"]}>.
+    INSERT INTO <${dataset.graph[0]}> {
+      <${dataset.catalog['@id']}> dcat:dataset <${dataset["@id"]}>.
   `
   insertQuery += buildDatasetTriples(dataset, profile)
   insertQuery += `}`
@@ -46,7 +50,6 @@ export async function insertDataset(
 
 export async function updateDataset(
   dataset: OcDataset,
-  graph: string,
   profile: OcPerson,
   auth?: Credentials
 ) {
@@ -56,9 +59,14 @@ export async function updateDataset(
   // form, then we insert new values.
   // Note that we keep `prov:qualifiedAttribution`
   // values.
+
+  if (!dataset.graph) {
+    throw Error('Dataset has no graph!')
+  }
+
   await executeSparqlUpdate(
     `
-    WITH <${graph}>
+    WITH <${dataset.graph[0]}>
     DELETE {
       <${dataset['@id']}> ?p ?o.
       ?temporal ?p2 ?o2.
@@ -94,7 +102,7 @@ export async function updateDataset(
       <${dataset['@id']}> ?p ?o.
     };
 
-    WITH <${graph}>
+    WITH <${dataset.graph[0]}>
     INSERT { ${buildDatasetTriples(dataset, profile)} };
     `
     , { auth }
diff --git a/src/stores/account.ts b/src/stores/account.ts
index 61a4371663186cd1974be6ab3b57b8766035ce72..8487808b9342d37af110ed73f28c232c2419a4b4 100644
--- a/src/stores/account.ts
+++ b/src/stores/account.ts
@@ -1,4 +1,4 @@
-import type { Credentials, OcMemberInfos, OcMembership, OcPerson } from '@/declarations'
+import type { Credentials, OcMemberInfos, OcMembership, OcPerson, OcRole } from '@/declarations'
 import { defineStore } from 'pinia'
 import { computed, ref, watch } from 'vue'
 
@@ -8,7 +8,8 @@ interface AccountState {
   profile: OcPerson | null
   memberships: OcMembership[] | null
   isAuthenticated: boolean
-  memberCommunitiesList: string[]
+  memberCommunitiesList: string[],
+  roleByOrganization: { [organization: string]: OcRole }
 }
 
 export const useAccountStore = defineStore<string, AccountState>('account', () => {
@@ -48,12 +49,27 @@ export const useAccountStore = defineStore<string, AccountState>('account', () =
     }
   })
 
+  const roleByOrganization = computed(() => {
+    const list: { [organization: string]: OcRole } = {}
+
+    if (!Array.isArray(memberships.value)) {
+      return []
+    }
+
+    memberships.value.forEach((membership: OcMembership) => {
+      list[membership.organization] = membership.role
+    })
+
+    return list
+  })
+
   return {
     auth,
     infos,
     profile,
     memberships,
     isAuthenticated,
-    memberCommunitiesList
+    memberCommunitiesList,
+    roleByOrganization
   }
 })
diff --git a/src/stores/tree.ts b/src/stores/tree.ts
index fde90529ac57893dc9d84d27be31f33c9a617ea7..fd82c90ddf82003f9239d9282bb3eb076e57edc9 100644
--- a/src/stores/tree.ts
+++ b/src/stores/tree.ts
@@ -109,7 +109,7 @@ export const useTreeStore = defineStore('tree', () => {
       account.auth?.value
     )
 
-    if (result.length){
+    if (result.length) {
       const ordered = reorderNodesFromHomeToResource(result, homeNodeUri, resourceId)
 
       await ordered.reduce(async (promiseChain, item) => {
@@ -198,7 +198,7 @@ export const useTreeStore = defineStore('tree', () => {
         return []
       }
       return path.map((node) => ocTreeNode2BreadcrumbItem(node))
-    } else {// Si il n'y a pas de noeud selectionné, le breadcrum est vide
+    } else {// Si il n'y a pas de noeud selectionné, le breadcrumb est vide
       return []
     }
   })