@communecter/cocolight-api-client 1.0.18 → 1.0.19
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/README.md +1 -1
- package/dist/cocolight-api-client.browser.js +3 -3
- package/dist/cocolight-api-client.cjs +1 -1
- package/dist/cocolight-api-client.mjs.js +1 -1
- package/package.json +2 -2
- package/src/Api.js +7 -4
- package/src/ApiClient.js +3 -3
- package/src/api/Badge.js +117 -0
- package/src/api/BaseEntity.js +162 -0
- package/src/api/EndpointApi.js +6 -6
- package/src/api/Event.js +144 -0
- package/src/api/News.js +134 -219
- package/src/api/Organization.js +117 -238
- package/src/api/Poi.js +158 -0
- package/src/api/Project.js +124 -234
- package/src/api/User.js +332 -91
- package/src/api/UserApi.js +5 -2
- package/src/endpoints.module.js +2 -2
- package/src/mixin/EntityMixin.js +320 -1
- package/src/mixin/MutualEntityMixin.js +224 -3
- package/src/mixin/UtilMixin.js +7 -3
- package/src/mixin/NewsMixin.js +0 -42
package/src/api/News.js
CHANGED
|
@@ -1,142 +1,44 @@
|
|
|
1
1
|
import { ApiError } from "../error.js";
|
|
2
|
-
import
|
|
3
|
-
import { UtilMixin } from "../mixin/UtilMixin.js";
|
|
4
|
-
|
|
5
|
-
// News.js
|
|
6
|
-
export class News {
|
|
7
|
-
#draftData = {};
|
|
8
|
-
#initialDraftData = {};
|
|
9
|
-
#serverData = null;
|
|
2
|
+
import BaseEntity from "./BaseEntity.js";
|
|
10
3
|
|
|
4
|
+
export class News extends BaseEntity {
|
|
11
5
|
static entityType = "news";
|
|
12
6
|
|
|
13
7
|
static SCHEMA_CONSTANTS = [
|
|
14
8
|
"ADD_NEWS"
|
|
15
9
|
];
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* @param {Object} data - Objet contenant { id }
|
|
21
|
-
* @param {Object} deps - Dépendances injectées (ex: User).
|
|
22
|
-
* @param {EndpointApi} deps.EndpointApi - Classe EndpointApi pour éviter les dépendances circulaires.
|
|
23
|
-
* @param {User} deps.User - Classe User pour éviter les dépendances circulaires.
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
constructor(parent, data = {}, deps = {}) {
|
|
27
|
-
this.__entityTag = "News";
|
|
28
|
-
|
|
29
|
-
if (!deps.EndpointApi) throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
|
|
30
|
-
if (!deps.User) throw new ApiError("User class must be injected.");
|
|
31
|
-
|
|
32
|
-
if (!parent) throw new ApiError("Parent is required.");
|
|
33
|
-
this.deps = deps;
|
|
34
|
-
this.EndpointApiClass = deps.EndpointApi;
|
|
35
|
-
|
|
36
|
-
if (parent?.__entityTag === "User" || parent?.__entityTag === "Organization" || parent?.__entityTag === "Project") {
|
|
37
|
-
this.apiClient = parent.apiClient;
|
|
38
|
-
this.parent = parent;
|
|
39
|
-
} else {
|
|
40
|
-
throw new ApiError("Invalid parent for News.");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this.endpointApi = typeof deps.EndpointApi === "function"
|
|
44
|
-
? new deps.EndpointApi(this.apiClient)
|
|
45
|
-
: (typeof deps.EndpointApi === "object"
|
|
46
|
-
? deps.EndpointApi
|
|
47
|
-
: (() => { throw new ApiError("deps.EndpointApi must be a class or instance."); })());
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
this.#serverData = null;
|
|
11
|
+
static ADD_BLOCKS = new Map([
|
|
12
|
+
["ADD_NEWS", "addNews"]
|
|
13
|
+
]);
|
|
51
14
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
constant: News.SCHEMA_CONSTANTS,
|
|
56
|
-
apiClient: this.apiClient,
|
|
57
|
-
transforms: this.transforms,
|
|
58
|
-
removeFields: this.removeFields
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
this.#initialDraftData = JSON.parse(JSON.stringify(draft)); // snapshot propre
|
|
62
|
-
this.#draftData = draft;
|
|
63
|
-
this.data = proxy;
|
|
15
|
+
static UPDATE_BLOCKS = new Map([
|
|
16
|
+
["ADD_NEWS", "updateNews"]
|
|
17
|
+
]);
|
|
64
18
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Getters en lecture seule pour chaque propriété
|
|
69
|
-
get id() {
|
|
70
|
-
return this.#draftData.id || null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
get isConnected() {
|
|
74
|
-
return this.apiClient.isConnected;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
get draftData() {
|
|
78
|
-
return this.#draftData;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
get initialDraftData() {
|
|
82
|
-
return this.#initialDraftData;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get serverData() {
|
|
86
|
-
return this.#serverData;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
get userId() {
|
|
90
|
-
return this.apiClient.userId;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
get isMe() {
|
|
94
|
-
return this.isConnected && this.userId === this.parent.id;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_setData(newData) {
|
|
98
|
-
this.#serverData = { ...newData };
|
|
19
|
+
defaultFields = {
|
|
99
20
|
|
|
100
|
-
|
|
101
|
-
data: { ...newData, ...this.defaultFields },
|
|
102
|
-
serverData: this.#serverData,
|
|
103
|
-
constant: News.SCHEMA_CONSTANTS,
|
|
104
|
-
apiClient: this.apiClient,
|
|
105
|
-
transforms: this.transforms,
|
|
106
|
-
removeFields: this.removeFields
|
|
107
|
-
});
|
|
108
|
-
this.#initialDraftData = JSON.parse(JSON.stringify(draft));
|
|
109
|
-
this.#draftData = draft;
|
|
110
|
-
this.data = proxy;
|
|
111
|
-
}
|
|
21
|
+
};
|
|
112
22
|
|
|
113
|
-
|
|
114
|
-
return News.entityType;
|
|
115
|
-
}
|
|
23
|
+
removeFields = [
|
|
116
24
|
|
|
117
|
-
|
|
118
|
-
const instance = new News(parent, {}, deps);
|
|
119
|
-
instance.#serverData = { ...data };
|
|
120
|
-
|
|
121
|
-
const { draft, proxy } = instance._buildDraftAndProxy({
|
|
122
|
-
data: { ...data, ...instance.defaultFields },
|
|
123
|
-
serverData: instance.#serverData,
|
|
124
|
-
constant: News.SCHEMA_CONSTANTS,
|
|
125
|
-
apiClient: instance.apiClient,
|
|
126
|
-
transforms: instance.transforms,
|
|
127
|
-
removeFields: instance.removeFields
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
instance.#draftData = draft;
|
|
131
|
-
instance.data = proxy;
|
|
132
|
-
|
|
133
|
-
return instance;
|
|
134
|
-
}
|
|
25
|
+
];
|
|
135
26
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
27
|
+
transforms = {
|
|
28
|
+
scope: val => val?.type,
|
|
29
|
+
mentions: val =>
|
|
30
|
+
Array.isArray(val)
|
|
31
|
+
? val.map(m => ({ ...m, count: parseInt(m.count) }))
|
|
32
|
+
: [],
|
|
33
|
+
mediaImg: val => {
|
|
34
|
+
const images = val?.images?.map(img => img.id).filter(Boolean) || [];
|
|
35
|
+
return images.length > 0 ? { countImages: images.length, images } : undefined;
|
|
36
|
+
},
|
|
37
|
+
mediaFile: val => {
|
|
38
|
+
const files = val?.files?.map(f => f.id).filter(Boolean) || [];
|
|
39
|
+
return files.length > 0 ? { countFiles: files.length, files } : undefined;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
140
42
|
|
|
141
43
|
/**
|
|
142
44
|
* Récupérer des actualités par IDs : Récupère des actualités à partir d’une liste d’identifiants.
|
|
@@ -144,93 +46,140 @@ export class News {
|
|
|
144
46
|
*/
|
|
145
47
|
async get() {
|
|
146
48
|
if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
|
|
147
|
-
|
|
49
|
+
|
|
148
50
|
const newsArray = await this.callIsConnected(() =>
|
|
149
51
|
this.endpointApi.getNewsById({ ids: [this.id] })
|
|
150
52
|
);
|
|
151
|
-
|
|
53
|
+
|
|
152
54
|
if (newsArray && Array.isArray(newsArray) && newsArray.length === 1) {
|
|
153
55
|
const data = newsArray[0];
|
|
154
|
-
this.#serverData = { ...data };
|
|
155
|
-
|
|
156
56
|
this._setData(data);
|
|
157
|
-
|
|
158
|
-
return this.#serverData;
|
|
57
|
+
return this.serverData;
|
|
159
58
|
}
|
|
160
59
|
throw new ApiError(`Aucune actualité trouvée pour l'ID ${this.id}`);
|
|
161
60
|
}
|
|
162
61
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
*/
|
|
168
|
-
async save() {
|
|
169
|
-
|
|
170
|
-
if(!this.isConnected){
|
|
171
|
-
throw new ApiError("Impossible de sauvegarder sans être connecté.");
|
|
62
|
+
|
|
63
|
+
async _add(payload) {
|
|
64
|
+
if (!this._calledFromSave) {
|
|
65
|
+
throw new Error("utilisation invalide de _add, utilisez save");
|
|
172
66
|
}
|
|
173
67
|
|
|
174
68
|
// si le texte est vide, on met un espace pour que le champ soit pris en compte car sur le serveur
|
|
175
69
|
// il y a une vérification de la taille du texte je pense
|
|
176
|
-
if(
|
|
177
|
-
|
|
70
|
+
if(payload.text === ""){
|
|
71
|
+
payload.text = " ";
|
|
178
72
|
}
|
|
179
|
-
|
|
180
|
-
const payload = { ...this.#draftData };
|
|
181
73
|
payload.parentId = this.parent.id;
|
|
182
74
|
payload.parentType = this.parent.getEntityType();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
75
|
+
|
|
76
|
+
// const data = await this.callIsConnected(() => this.endpointApi.addNews(payload));
|
|
77
|
+
// this._draftData.id = data.object.id;
|
|
78
|
+
// // TODO : voir si j'ai ce qui faut dans reponseData de ADD_NEWS pour mettre à jour #serverData
|
|
79
|
+
// // c'est dans reponseData.object
|
|
80
|
+
// // if(data?.object){
|
|
81
|
+
// // this._serverData = { ...data.object };
|
|
82
|
+
// // }
|
|
83
|
+
|
|
84
|
+
for (const [constant, methodName] of News.ADD_BLOCKS) {
|
|
85
|
+
const blockData = this._extractChangedFieldsFromSchema(
|
|
86
|
+
this.apiClient,
|
|
87
|
+
constant,
|
|
88
|
+
{ ...payload, ...this.defaultFields },
|
|
89
|
+
() => {}
|
|
90
|
+
);
|
|
91
|
+
if (blockData && Object.keys(blockData).length > 0) {
|
|
92
|
+
const data = await this[methodName](blockData);
|
|
93
|
+
if (!this.id && data?.object?.id) {
|
|
94
|
+
this._draftData.id = data.object.id;
|
|
95
|
+
// this._serverData = { ...data.object };
|
|
96
|
+
}
|
|
203
97
|
}
|
|
204
|
-
// await this.refresh();
|
|
205
|
-
return reponseData;
|
|
206
98
|
}
|
|
207
99
|
}
|
|
208
100
|
|
|
101
|
+
async _update(payload) {
|
|
102
|
+
if (!this._calledFromSave) {
|
|
103
|
+
throw new Error("utilisation invalide de _update, utilisez save");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (payload.id) delete payload.id;
|
|
107
|
+
|
|
108
|
+
// si le texte est vide, on met un espace pour que le champ soit pris en compte car sur le serveur
|
|
109
|
+
// il y a une vérification de la taille du texte je pense
|
|
110
|
+
if(payload?.text === ""){
|
|
111
|
+
payload.text = " ";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
payload.parentId = this.parent.id;
|
|
115
|
+
payload.parentType = this.parent.getEntityType();
|
|
116
|
+
payload.idNews = this.id;
|
|
117
|
+
|
|
118
|
+
let hasChanged = false;
|
|
119
|
+
const data = await this.callIsConnected(() => this.endpointApi.updateNews(payload));
|
|
120
|
+
// TODO : voir si j'ai ce qui faut dans data de UPDATE_NEWS pour mettre à jour #serverData
|
|
121
|
+
// c'est dans data.object
|
|
122
|
+
if(data?.object){
|
|
123
|
+
this._serverData = { ...data.object };
|
|
124
|
+
}
|
|
125
|
+
hasChanged = true;
|
|
126
|
+
return hasChanged;
|
|
127
|
+
|
|
128
|
+
// if (payload.id) delete payload.id;
|
|
129
|
+
// let hasChanged = false;
|
|
130
|
+
|
|
131
|
+
// for (const [constant, methodName] of News.UPDATE_BLOCKS) {
|
|
132
|
+
// const blockData = this._extractChangedFieldsFromSchema(
|
|
133
|
+
// this.apiClient,
|
|
134
|
+
// constant,
|
|
135
|
+
// { ...payload, ...this.defaultFields },
|
|
136
|
+
// () => this.initialDraftData,
|
|
137
|
+
// this.removeFields
|
|
138
|
+
// );
|
|
139
|
+
// if (blockData && Object.keys(blockData).length > 0) {
|
|
140
|
+
// await this[methodName](blockData);
|
|
141
|
+
// hasChanged = true;
|
|
142
|
+
// }
|
|
143
|
+
// }
|
|
144
|
+
|
|
145
|
+
// return hasChanged;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async addNews(data = {}) {
|
|
149
|
+
return this.callIsConnected(() => this.endpointApi.addNews(data));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async updateNews(data = {}) {
|
|
153
|
+
return this.callIsConnected(() => this.endpointApi.updateNews(data));
|
|
154
|
+
}
|
|
209
155
|
|
|
210
156
|
async addMention({ slug, id }) {
|
|
211
157
|
try {
|
|
212
158
|
if (!slug && !id) {
|
|
213
159
|
throw new ApiError("Vous devez fournir un slug ou un id pour ajouter une mention.");
|
|
214
160
|
}
|
|
215
|
-
|
|
161
|
+
|
|
162
|
+
const userInstance = await this.entity("citoyens", { id, slug });
|
|
163
|
+
// const userInstance = new this.deps.User(this.apiClient, { id, slug }, { EndpointApi: this.endpointApi });
|
|
216
164
|
const user = userInstance.serverData;
|
|
217
|
-
|
|
218
|
-
|
|
165
|
+
|
|
166
|
+
if (!this._draftData.mentions) {
|
|
167
|
+
this._draftData.mentions = [];
|
|
219
168
|
}
|
|
220
169
|
// Vérification si la mention existe déjà
|
|
221
|
-
if (this
|
|
170
|
+
if (this._draftData.mentions.find((mention) => mention.id === user.id)) {
|
|
222
171
|
// Si la mention existe déjà, on incrémente le compteur
|
|
223
|
-
this
|
|
172
|
+
this._draftData.mentions = this._draftData.mentions.map((mention) => {
|
|
224
173
|
if (mention.id === user.id) {
|
|
225
174
|
mention.count += 1;
|
|
226
175
|
}
|
|
227
176
|
return mention;
|
|
228
177
|
});
|
|
229
|
-
return this
|
|
178
|
+
return this._draftData.mentions;
|
|
230
179
|
}
|
|
231
180
|
const mention = { id: user.id, slug: user.slug, type: userInstance.getEntityType(), name: user.name, value: user.name, count: 1 };
|
|
232
|
-
this
|
|
233
|
-
return this
|
|
181
|
+
this._draftData.mentions.push(mention);
|
|
182
|
+
return this._draftData.mentions;
|
|
234
183
|
} catch (error) {
|
|
235
184
|
this.apiClient._logger.error("Erreur lors de l'ajout de la mention :", error);
|
|
236
185
|
throw error;
|
|
@@ -247,11 +196,11 @@ export class News {
|
|
|
247
196
|
image = await this._validateImage(image);
|
|
248
197
|
const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsImage: image };
|
|
249
198
|
const dataImage = await this.callIsConnected(() => this.endpointApi.addImageNews(data));
|
|
250
|
-
if (this
|
|
251
|
-
this
|
|
252
|
-
this
|
|
199
|
+
if (this._draftData.mediaImg) {
|
|
200
|
+
this._draftData.mediaImg.countImages = this._draftData.mediaImg.countImages + 1;
|
|
201
|
+
this._draftData.mediaImg.images.push(dataImage.id);
|
|
253
202
|
} else {
|
|
254
|
-
this
|
|
203
|
+
this._draftData.mediaImg = { countImages: 1, images: [dataImage.id] };
|
|
255
204
|
}
|
|
256
205
|
return dataImage;
|
|
257
206
|
}
|
|
@@ -264,11 +213,11 @@ export class News {
|
|
|
264
213
|
file = await this._validateFile(file);
|
|
265
214
|
const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsFile: file };
|
|
266
215
|
const dataFile = await this.callIsConnected(() =>this.endpointApi.addFileNews(data));
|
|
267
|
-
if (this
|
|
268
|
-
this
|
|
269
|
-
this
|
|
216
|
+
if (this._draftData.mediaFile) {
|
|
217
|
+
this._draftData.mediaFile.countFiles = this._draftData.mediaFile.countFiles + 1;
|
|
218
|
+
this._draftData.mediaFile.files.push(dataFile);
|
|
270
219
|
} else {
|
|
271
|
-
this
|
|
220
|
+
this._draftData.mediaFile = { countFiles: 1, files: [dataFile] };
|
|
272
221
|
}
|
|
273
222
|
return dataFile;
|
|
274
223
|
}
|
|
@@ -283,45 +232,11 @@ export class News {
|
|
|
283
232
|
}
|
|
284
233
|
const data = { pathParams: { id: this.id } };
|
|
285
234
|
await this.callIsConnected(() => this.endpointApi.deleteNews(data));
|
|
286
|
-
this
|
|
287
|
-
this
|
|
288
|
-
this
|
|
235
|
+
this._draftData = {};
|
|
236
|
+
this._serverData = null;
|
|
237
|
+
this._draftData.id = null;
|
|
289
238
|
this._isDeleted = true;
|
|
290
239
|
}
|
|
291
240
|
|
|
292
|
-
_updateInitialDraftSnapshot() {
|
|
293
|
-
this.#initialDraftData = JSON.parse(JSON.stringify(this.#draftData));
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
hasChanges() {
|
|
297
|
-
return JSON.stringify(this.#draftData) !== JSON.stringify(this.#initialDraftData);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
defaultFields = {
|
|
301
|
-
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
removeFields = [
|
|
305
|
-
|
|
306
|
-
];
|
|
307
|
-
|
|
308
|
-
transforms = {
|
|
309
|
-
scope: val => val?.type,
|
|
310
|
-
mentions: val =>
|
|
311
|
-
Array.isArray(val)
|
|
312
|
-
? val.map(m => ({ ...m, count: parseInt(m.count) }))
|
|
313
|
-
: [],
|
|
314
|
-
mediaImg: val => {
|
|
315
|
-
const images = val?.images?.map(img => img.id).filter(Boolean) || [];
|
|
316
|
-
return images.length > 0 ? { countImages: images.length, images } : undefined;
|
|
317
|
-
},
|
|
318
|
-
mediaFile: val => {
|
|
319
|
-
const files = val?.files?.map(f => f.id).filter(Boolean) || [];
|
|
320
|
-
return files.length > 0 ? { countFiles: files.length, files } : undefined;
|
|
321
|
-
}
|
|
322
|
-
};
|
|
323
241
|
|
|
324
242
|
}
|
|
325
|
-
|
|
326
|
-
// Incorporation du mixin dans Organization
|
|
327
|
-
Object.assign(News.prototype, UtilMixin, DraftStateMixin);
|