@open-commune/web 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/forms/inputs/input-editor.vue +3 -3
- package/components/forms/inputs/input-files.vue +1 -1
- package/composables/core/domains/use-media.ts +2 -2
- package/editor/index.ts +7 -7
- package/models/_factory.js +1 -1
- package/models/{_commun.js → _open-commune.js} +10 -10
- package/models/collection.js +1 -1
- package/models/entrance.js +1 -1
- package/models/media.js +1 -1
- package/models/organization.js +2 -2
- package/models/record.js +1 -1
- package/models/role.js +1 -1
- package/models/user.js +1 -1
- package/package.json +2 -2
- package/pages/index/welcome/[token].vue +1 -1
- package/pages/management/roles.vue +1 -1
- package/store/layout/workspace.js +1 -1
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
v-model="doc"
|
|
53
53
|
:image="false"
|
|
54
54
|
:mention="false"
|
|
55
|
-
:starter-kit="
|
|
55
|
+
:starter-kit="openCommuneStarterKit"
|
|
56
56
|
:extensions="extensions"
|
|
57
57
|
:handlers="customHandlers"
|
|
58
58
|
:enable-content-check="true"
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
// stringified JSON, and emits IN THE SAME SHAPE it received.
|
|
154
154
|
import { ref, watch } from 'vue'
|
|
155
155
|
import { mapEditorItems } from '@nuxt/ui/utils/editor'
|
|
156
|
-
import {
|
|
156
|
+
import { openCommuneExtensions, openCommuneStarterKit, sanitizeDoc, EMBED_SERVICES } from '~/editor'
|
|
157
157
|
|
|
158
158
|
const $emitters = defineEmits(['change'])
|
|
159
159
|
const $props = defineProps({
|
|
@@ -164,7 +164,7 @@ const $props = defineProps({
|
|
|
164
164
|
})
|
|
165
165
|
|
|
166
166
|
const { media } = useCore()
|
|
167
|
-
const extensions =
|
|
167
|
+
const extensions = openCommuneExtensions(media.forEditor())
|
|
168
168
|
const toast = useToast()
|
|
169
169
|
const uEditor = ref()
|
|
170
170
|
|
|
@@ -45,7 +45,7 @@ const inputFile = ref(null)
|
|
|
45
45
|
const _handleClick = () => inputFile.value.click()
|
|
46
46
|
|
|
47
47
|
const _createMedia = async ({ name, mime, file }) => {
|
|
48
|
-
// Request for S3 pre-signed url (le nom alimente la clé S3 côté
|
|
48
|
+
// Request for S3 pre-signed url (le nom alimente la clé S3 côté Open Commune)
|
|
49
49
|
const { _id, url } = await Media.getS3PreSignedUrl({ mime, name })
|
|
50
50
|
|
|
51
51
|
// Put media on amazon S3
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenCommuneEditorMedia } from '@open-commune/editor'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Media domain composable: tRPC calls plus the direct-to-S3 upload step.
|
|
@@ -76,7 +76,7 @@ export default function useMedia() {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/** The upload/resolve pair in the shape the editor extensions expect. */
|
|
79
|
-
const forEditor = ():
|
|
79
|
+
const forEditor = (): OpenCommuneEditorMedia => ({ upload, fetch: resolve })
|
|
80
80
|
|
|
81
81
|
return { upload, resolve, forEditor }
|
|
82
82
|
}
|
package/editor/index.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { VueNodeViewRenderer } from '@tiptap/vue-3'
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
openCommuneStarterKit,
|
|
4
|
+
openCommuneSchemaExtensions,
|
|
5
5
|
sanitizeDoc,
|
|
6
6
|
EMBED_SERVICES,
|
|
7
7
|
UID_TYPES,
|
|
8
|
-
type
|
|
8
|
+
type OpenCommuneEditorMedia,
|
|
9
9
|
} from '@open-commune/editor'
|
|
10
10
|
import CalloutView from './views/CalloutView.vue'
|
|
11
11
|
import FileView from './views/FileView.vue'
|
|
@@ -16,8 +16,8 @@ import DetailsSummaryView from './views/DetailsSummaryView.vue'
|
|
|
16
16
|
import DetailsContentView from './views/DetailsContentView.vue'
|
|
17
17
|
import UploadView from './views/UploadView.vue'
|
|
18
18
|
|
|
19
|
-
export {
|
|
20
|
-
export type {
|
|
19
|
+
export { openCommuneStarterKit, UID_TYPES, sanitizeDoc, EMBED_SERVICES }
|
|
20
|
+
export type { OpenCommuneEditorMedia }
|
|
21
21
|
|
|
22
22
|
const VIEWS: Record<string, any> = {
|
|
23
23
|
callout: CalloutView,
|
|
@@ -34,8 +34,8 @@ const VIEWS: Record<string, any> = {
|
|
|
34
34
|
* Browser entry: the shared extension set (@open-commune/editor) with the admin's
|
|
35
35
|
* Vue node views attached.
|
|
36
36
|
*/
|
|
37
|
-
export function
|
|
38
|
-
return
|
|
37
|
+
export function openCommuneExtensions(media: Partial<OpenCommuneEditorMedia> = {}) {
|
|
38
|
+
return openCommuneSchemaExtensions(media).map((extension: any) => {
|
|
39
39
|
const view = VIEWS[extension.name]
|
|
40
40
|
return view
|
|
41
41
|
? extension.extend({ addNodeView: () => VueNodeViewRenderer(view) })
|
package/models/_factory.js
CHANGED
|
@@ -4,7 +4,7 @@ import { useWorkspaceStore } from '~/store/layout/workspace'
|
|
|
4
4
|
const HOOK_DEFAULT = (val) => val
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Couche d'accès au monolithe
|
|
7
|
+
* Couche d'accès au monolithe Open Commune : chaque modèle implémente ses méthodes
|
|
8
8
|
* via le client tRPC (plan admin). L'interface publique legacy est conservée
|
|
9
9
|
* (read/list/create/update/remove + repo pinia-orm + hooks onRetrieve/onSave)
|
|
10
10
|
* pour ne pas toucher aux pages/composants.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pont legacy ↔
|
|
2
|
+
* Pont legacy ↔ Open Commune partagé par les modèles : cache des définitions de
|
|
3
3
|
* collections, conversion attributes[] ↔ fields[] (même table que le
|
|
4
4
|
* migrateur packages/legacy-migrate) et conversion des VALEURS de champs.
|
|
5
5
|
*
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* circule tel quel.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
// ── Mapping composants de formulaire ↔ types de champs
|
|
13
|
+
// ── Mapping composants de formulaire ↔ types de champs Open Commune ──────────────
|
|
14
14
|
export const COMPONENT_TO_FIELD_TYPE = {
|
|
15
15
|
'input-text': 'text',
|
|
16
16
|
'input-textarea': 'text',
|
|
@@ -33,7 +33,7 @@ export const COMPONENT_TO_FIELD_TYPE = {
|
|
|
33
33
|
'handler-steps': 'steps'
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// Composant par défaut pour AFFICHER un champ
|
|
36
|
+
// Composant par défaut pour AFFICHER un champ Open Commune dans l'éditeur de
|
|
37
37
|
// collections (perte assumée : text ne distingue plus input-text/textarea).
|
|
38
38
|
export const FIELD_TYPE_TO_COMPONENT = {
|
|
39
39
|
text: 'input-text',
|
|
@@ -64,7 +64,7 @@ export async function getUsersById(trpc) {
|
|
|
64
64
|
return _usersById
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
/** id utilisateur
|
|
67
|
+
/** id utilisateur Open Commune → objet user legacy attendu par avatar-with-text. */
|
|
68
68
|
export function userRefToLegacy(usersById, id) {
|
|
69
69
|
if (!id) return {}
|
|
70
70
|
const user = usersById.get(id)
|
|
@@ -140,7 +140,7 @@ export function toServerValue(field, value) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// ── Conversion des définitions attributes[] ↔ fields[] ─────────────────────
|
|
143
|
-
/** FieldDefinition
|
|
143
|
+
/** FieldDefinition Open Commune → attribut legacy (édition de collections). */
|
|
144
144
|
export function fieldToAttribute(field) {
|
|
145
145
|
return {
|
|
146
146
|
name: field.name,
|
|
@@ -153,7 +153,7 @@ export function fieldToAttribute(field) {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
/** Attribut legacy → FieldDefinition
|
|
156
|
+
/** Attribut legacy → FieldDefinition Open Commune (null si non mappable). */
|
|
157
157
|
export function attributeToField(attribute) {
|
|
158
158
|
const name = String(attribute.name ?? '')
|
|
159
159
|
// title/name/slug sont des COLONNES d'entrée, pas des champs (iso migrateur).
|
|
@@ -184,8 +184,8 @@ export function attributeToField(attribute) {
|
|
|
184
184
|
return field
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
// ── Projections d'entités
|
|
188
|
-
/** Entry
|
|
187
|
+
// ── Projections d'entités Open Commune → enregistrements legacy ──────────────────
|
|
188
|
+
/** Entry Open Commune → record legacy aplati par onRetrieve côté composants. */
|
|
189
189
|
export function entryToRecord(definition, entry, usersById = new Map()) {
|
|
190
190
|
const fieldsByName = new Map(definition.fields.map((field) => [field.name, field]))
|
|
191
191
|
return {
|
|
@@ -208,7 +208,7 @@ export function entryToRecord(definition, entry, usersById = new Map()) {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
/** CollectionDefinition
|
|
211
|
+
/** CollectionDefinition Open Commune → collection legacy. */
|
|
212
212
|
export function definitionToCollection(definition) {
|
|
213
213
|
return {
|
|
214
214
|
_id: definition.id,
|
|
@@ -227,7 +227,7 @@ export function definitionToCollection(definition) {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
/** Media
|
|
230
|
+
/** Media Open Commune (objects signés) → media legacy. */
|
|
231
231
|
export function mediaToLegacy(media) {
|
|
232
232
|
return {
|
|
233
233
|
_id: media.id,
|
package/models/collection.js
CHANGED
package/models/entrance.js
CHANGED
|
@@ -17,7 +17,7 @@ const _entranceModel = class Entrance extends Model {
|
|
|
17
17
|
const _entranceAPI = class EntranceAPI extends ModelAPI {
|
|
18
18
|
/**
|
|
19
19
|
* Le flux legacy confirm-email → define-password est remplacé par
|
|
20
|
-
* l'acceptation d'invitation
|
|
20
|
+
* l'acceptation d'invitation Open Commune (une seule étape, publique).
|
|
21
21
|
*/
|
|
22
22
|
async acceptInvitation({ token, name, password }) {
|
|
23
23
|
return this.trpc.auth.acceptInvitation.mutate({ token, name, password })
|
package/models/media.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Media Model
|
|
2
2
|
import { Model } from 'pinia-orm'
|
|
3
3
|
import ModelAPI from '~/models/_factory'
|
|
4
|
-
import { mediaToLegacy } from '~/models/
|
|
4
|
+
import { mediaToLegacy } from '~/models/_open-commune'
|
|
5
5
|
|
|
6
6
|
const _mediaModel = class Media extends Model {
|
|
7
7
|
// This is the name used as module name of the Vuex Store.
|
package/models/organization.js
CHANGED
|
@@ -32,11 +32,11 @@ const _organizationModel = class Organization extends Model {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
// Clés du modèle
|
|
35
|
+
// Clés du modèle Open Commune (revue 28/07 : address JSON, colonnes retirées).
|
|
36
36
|
const UPDATABLE = ['name', 'type', 'slug', 'description', 'address', 'deployment', 'settings']
|
|
37
37
|
|
|
38
38
|
const _organizationAPI = class OrganizationAPI extends ModelAPI {
|
|
39
|
-
/** Organization
|
|
39
|
+
/** Organization Open Commune (singleton) → organisation legacy, _id = slug (routes). */
|
|
40
40
|
async _toLegacy(organization) {
|
|
41
41
|
const definitions = await this.trpc.collections.list.query()
|
|
42
42
|
return {
|
package/models/record.js
CHANGED
package/models/role.js
CHANGED
|
@@ -26,7 +26,7 @@ const _roleModel = class Role extends Model {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Les rôles paramétrables du legacy sont remplacés par le modèle fixe
|
|
29
|
+
* Les rôles paramétrables du legacy sont remplacés par le modèle fixe Open Commune
|
|
30
30
|
* (admin / redacteur). La liste est statique ; le CRUD est inerte.
|
|
31
31
|
*/
|
|
32
32
|
const ROLES = [
|
package/models/user.js
CHANGED
|
@@ -37,7 +37,7 @@ const _userModel = class User extends Model {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
/** PublicUser
|
|
40
|
+
/** PublicUser Open Commune { id, email, name, role } → user legacy. */
|
|
41
41
|
function userToLegacy(user) {
|
|
42
42
|
return {
|
|
43
43
|
_id: user.id,
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@nuxt/kit": "^4.5.1",
|
|
19
19
|
"@nuxt/ui": "^4.3.0",
|
|
20
20
|
"@open-commune/core": "^0.2.0",
|
|
21
|
-
"@open-commune/editor": "^0.1.
|
|
21
|
+
"@open-commune/editor": "^0.1.5",
|
|
22
22
|
"@pinia-orm/nuxt": "^2.0.0",
|
|
23
23
|
"@pinia/nuxt": "^1.0.1",
|
|
24
24
|
"@tanstack/vue-query": "^5.101.4",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"description": "The Open Commune application: the admin interface and the server, on a single origin.",
|
|
42
42
|
"license": "AGPL-3.0-or-later",
|
|
43
|
-
"version": "0.2.
|
|
43
|
+
"version": "0.2.5",
|
|
44
44
|
"type": "module",
|
|
45
45
|
"main": "./nuxt.config.ts",
|
|
46
46
|
"files": [
|
|
@@ -50,7 +50,7 @@ import { useNotificationsStore } from '~/store/layout/notifications'
|
|
|
50
50
|
import InputText from '~/components/forms/inputs/input-text'
|
|
51
51
|
import ButtonPrimary from '~/components/elements/buttons/primary'
|
|
52
52
|
|
|
53
|
-
// Flux invitation
|
|
53
|
+
// Flux invitation Open Commune : la validité du jeton est vérifiée au moment de
|
|
54
54
|
// l'acceptation (auth.acceptInvitation) — plus d'étape « confirmation d'email »
|
|
55
55
|
// préalable.
|
|
56
56
|
//
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<section class="w-full">
|
|
3
|
-
<!-- Rôles figés par
|
|
3
|
+
<!-- Rôles figés par Open Commune (admin / rédacteur) : consultation seule. -->
|
|
4
4
|
<p class="mb-6 rounded-md bg-amber-50 border border-amber-200 px-4 py-3 text-sm text-amber-800">
|
|
5
5
|
Les rôles sont désormais prédéfinis (administrateur, rédacteur) et ne sont plus personnalisables.
|
|
6
6
|
</p>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineStore } from 'pinia'
|
|
2
2
|
|
|
3
|
-
// Single-tenant : les permissions dérivent du rôle
|
|
3
|
+
// Single-tenant : les permissions dérivent du rôle Open Commune de l'utilisateur.
|
|
4
4
|
// `manage:all` est un joker CASL (toute action sur tout sujet).
|
|
5
5
|
//
|
|
6
6
|
// `redacteur` reprend EXACTEMENT le rôle legacy « Éditeur de contenu », que
|