Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
66170c3
add: publier.etalab.studio into admin
geoffreyaldebert Oct 14, 2025
9537255
feat: not only tableschema
geoffreyaldebert Oct 15, 2025
2ed1e8c
feat: optional param in url to auto select schema
geoffreyaldebert Oct 15, 2025
7e4a95a
feat: allow producerselect component to propose or not user
geoffreyaldebert Oct 15, 2025
b0d4a34
feat: add paddedcontainer if no organisation for producerselect
geoffreyaldebert Oct 15, 2025
8f5efc2
feat: better visualization of schema cards and selection
geoffreyaldebert Oct 15, 2025
b86fccb
feat: do not propose to modify resource card when tableschema
geoffreyaldebert Oct 15, 2025
6c2444f
style: table
geoffreyaldebert Oct 15, 2025
1c1ba54
feat: do not propose to go next when table is not validated
geoffreyaldebert Oct 15, 2025
3701ba8
fixes
geoffreyaldebert Oct 16, 2025
01caf83
Merge branch 'main' into publier-schema
nicolaskempf57 Oct 17, 2025
7620690
Merge branch 'main' into publier-schema
nicolaskempf57 Oct 17, 2025
a902656
Merge branch 'main' into publier-schema
maudetes Oct 22, 2025
d383ecb
Fix package.json & lock
maudetes Oct 23, 2025
708dab3
Fix PaddedContainer import
maudetes Oct 23, 2025
1bf8c9c
Use useTranslation instead of useI18n
maudetes Oct 23, 2025
7f9666b
fix: after merge missing testid
nicolaskempf57 Oct 24, 2025
02c49d6
refac: use href and tailwind classes
nicolaskempf57 Oct 24, 2025
feec735
refac: update schema types
nicolaskempf57 Oct 24, 2025
38b36c8
refac: remove unnecessary externals
nicolaskempf57 Oct 24, 2025
85dafae
fix: step 1 and move to FormWithAccordions
nicolaskempf57 Oct 24, 2025
c10550f
fix: dataset search outside of schema
nicolaskempf57 Oct 27, 2025
98f5309
refac: improve schema search UX
nicolaskempf57 Oct 27, 2025
e05ad41
refac: fix type
nicolaskempf57 Oct 27, 2025
6e7d418
refac: use tailwindcss classes
nicolaskempf57 Oct 27, 2025
c8b7319
fix: import
nicolaskempf57 Oct 27, 2025
d1bf158
refac: remove some states
nicolaskempf57 Oct 28, 2025
7c49bbe
refac: remove duplicated states
nicolaskempf57 Oct 28, 2025
0511052
refac: remove states and simplify
nicolaskempf57 Oct 29, 2025
d4da863
feat: update popup
nicolaskempf57 Oct 29, 2025
85b33e4
feat: improves based on issue comments
nicolaskempf57 Oct 29, 2025
dc0364f
refac: use Banner instead of Alert
nicolaskempf57 Oct 30, 2025
492bf0c
Merge branch 'main' into publier-schema
nicolaskempf57 Nov 6, 2025
b94876e
fix(schema): redesign SchemaCard
nicolaskempf57 Nov 7, 2025
4851d3e
feat: add schema card on step 2
nicolaskempf57 Nov 7, 2025
5e7b78e
refactor(schema): add tabular editor component with CSV parsing
nicolaskempf57 Nov 12, 2025
b819d71
fix(DatasetsSelect): prevent card overflow with min-w-0
nicolaskempf57 Nov 13, 2025
47e384a
refactor(TabularEditor): use icon props and remove debug logs
nicolaskempf57 Nov 13, 2025
20fd2e0
refactor(Step3): use v-model instead of useState
nicolaskempf57 Nov 13, 2025
ab2c2d8
refactor(structured): improve data flow and UX
nicolaskempf57 Nov 13, 2025
6ba284c
fix(strutured): new dataset saved as user one
nicolaskempf57 Nov 13, 2025
16b9a37
fix(structured): correct redirect after step 4
nicolaskempf57 Nov 13, 2025
5d675cd
Merge branch 'main' into publier-schema
maudetes Nov 17, 2025
fd3b53a
Merge branch 'main' into publier-schema
maudetes Nov 21, 2025
887707f
feat: add feature flag for structured dataset form
nicolaskempf57 Nov 24, 2025
20962c2
chore: lock updates
nicolaskempf57 Nov 24, 2025
0afb011
chore: another lock changes
nicolaskempf57 Nov 24, 2025
fb38297
Merge branch 'main' into publier-schema
nicolaskempf57 Nov 27, 2025
45d0cd3
fix: types
nicolaskempf57 Nov 27, 2025
6475a56
feat(harvest): show organization for which the user is admin only in …
maudetes Nov 28, 2025
e341246
Simplify useAPI organization url
maudetes Nov 28, 2025
c1cefa4
Use harvester illustration
maudetes Nov 28, 2025
9fa91bb
Merge branch 'main' into feat/producer-select-for-org-and-admin-only-…
maudetes Nov 28, 2025
5d681e9
Use isUserOrgAdmin util and remove redirectOn404
maudetes Nov 28, 2025
a45f381
Fix isOrgAdmin in harvester configuration
maudetes Nov 28, 2025
cbc1e59
Merge branch 'main' into feat/producer-select-for-org-and-admin-only-…
maudetes Nov 28, 2025
f05fa90
organization may be null
maudetes Nov 28, 2025
4d19110
Merge branch 'main' into feat/producer-select-for-org-and-admin-only-…
maudetes Dec 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions components/Harvesters/DescribeHarvester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class="mb-4 flex items-center space-x-5"
>
<NuxtImg
src="/illustrations/truck.svg"
src="/illustrations/harvester.svg"
loading="lazy"
class="size-14 shrink-0"
alt=""
Expand All @@ -33,11 +33,30 @@
<FieldsetElement form-key="owned">
<ProducerSelect
v-model="form.owned"
:label="t(`Vérifiez l'identité avec laquelle vous souhaitez publier`)"
:label="t(`Sélectionnez votre organisation`)"
:required="true"
:organizations-only="true"
:admin-only="true"
:error-text="getFirstError('owned')"
:warning-text="getFirstWarning('owned')"
/>
<template #accordion>
<HelpAccordion :title="$t(`Choisir l'organisation pour laquelle vous souhaitez mettre en place un moissonneur`)">
<p class="m-0 mb-4">
{{ $t("La création d'un moissonneur doit obligatoirement se faire au nom d'une organisation et nécessite les droits administrateurs. Sélectionnez une organisation dont vous êtes administrateur.") }}
</p>
<p class="m-0">
{{ $t("Si votre organisation n'existe pas encore, vous devez d'abord") }}
<NuxtLink
to="/admin/organizations/new/"
class="link"
target="_blank"
>
{{ $t("la créer ici") }}
</NuxtLink>.
</p>
</HelpAccordion>
</template>
</FieldsetElement>
</FormFieldset>

Expand Down
24 changes: 19 additions & 5 deletions components/ProducerSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
</template>

<script setup lang="ts">
import { useGetUserAvatar, BrandedButton, PaddedContainer, type Organization, type Owned, type User, OrganizationLogo } from '@datagouv/components-next'
import { useGetUserAvatar, BrandedButton, OrganizationLogo, PaddedContainer, type Organization, type Owned, type User } from '@datagouv/components-next'
import { isUserOrgAdmin, useMe } from '~/utils/auth'

const getUserAvatar = useGetUserAvatar()

Expand All @@ -67,24 +68,37 @@ const props = withDefaults(defineProps<{
all?: boolean
required?: boolean
organizationsOnly?: boolean
adminOnly?: boolean
}>(), {
all: false,
required: false,
organizationsOnly: false,
adminOnly: false,
})
const model = defineModel<Owned | null>({ required: true })

const { t } = useTranslation()
const user = useMe()
const { $api } = useNuxtApp()

const ownedOptions = computed<Array<Owned>>(() => {
const organizations = user.value.organizations.map(organization => ({ organization, owner: null }))
// we fetch full organization object because we need members details
// in case we want to filter on admin only organizations
const organizations = await Promise.all(
Comment on lines +84 to +86
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any more straightforward way to know organizations for which the user is admin?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The computed code can be simplified when this one is merged https://github.com/datagouv/cdata/pull/790/files.

But if we don't want to query all organizations, I think members should be added to the api/1/me

Copy link
Contributor Author

@maudetes maudetes Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it seems overkill to get the entire organization members on api/1/me for now!
We may change it if we have other use cases than harvest publication form.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we expose a permission field instead ? Like the one in the dataservice model

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think it's better to expose a permission field…

user.value.organizations.map(async (org) => {
const { data: organization } = await useAPI<Organization>(`/api/1/organizations/${org.id}`)
return organization.value
}),
)

const ownedOptions = computed<Array<Owned>>(() => {
let orgs = organizations.map(organization => ({ organization, owner: null }))
if (props.adminOnly) {
orgs = orgs.filter(org => isUserOrgAdmin(user.value, org.organization))
}
if (props.organizationsOnly) {
return organizations
return orgs
}
return [...organizations, { owner: user.value, organization: null }]
return [...orgs, { owner: user.value, organization: null }]
})

const hasOrganizations = computed(() => {
Expand Down
7 changes: 5 additions & 2 deletions pages/admin/harvesters/[id]/configuration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@

<script setup lang="ts">
import { RiDeleteBin6Line } from '@remixicon/vue'
import { BannerAction, BrandedButton } from '@datagouv/components-next'
import { BannerAction, BrandedButton, type Organization } from '@datagouv/components-next'
import DescribeHarvester from '~/components/Harvesters/DescribeHarvester.vue'
import JobPage from '~/components/Harvesters/JobPage.vue'
import PreviewLoader from '~/components/Harvesters/PreviewLoader.vue'
Expand All @@ -107,7 +107,10 @@ const me = useMe()
const sourceUrl = computed(() => `/api/1/harvest/source/${route.params.id}`)
const { data: harvester, refresh } = await useAPI<HarvesterSource>(sourceUrl, { redirectOn404: true })

const isOrgAdmin = computed(() => !harvester.value.organization || isUserOrgAdmin(me.value, harvester.value.organization))
// we fetch full organization object if exists because we need members details for isOrgAdmin
const organization = harvester.value.organization ? (await useAPI<Organization>(`/api/1/organizations/${harvester.value.organization.id}`)).data : null

const isOrgAdmin = computed(() => !harvester.value.organization || isUserOrgAdmin(me.value, organization?.value))

const loading = ref(false)

Expand Down
Loading