firstly 0.0.6 → 0.0.8

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/esm/FF_Entity.js +20 -4
  3. package/esm/ROUTES.d.ts +11 -11
  4. package/esm/ROUTES.js +5 -5
  5. package/esm/SqlDatabase/FF_LogToConsole.d.ts +4 -1
  6. package/esm/SqlDatabase/FF_LogToConsole.js +15 -8
  7. package/esm/api/index.d.ts +2 -2
  8. package/esm/api/index.js +9 -9
  9. package/esm/auth/Adapter.js +1 -7
  10. package/esm/auth/AuthController.server.d.ts +1 -2
  11. package/esm/auth/AuthController.server.js +96 -65
  12. package/esm/auth/RoleHelpers.d.ts +1 -1
  13. package/esm/auth/RoleHelpers.js +9 -9
  14. package/esm/auth/client/Auth.d.ts +11 -4
  15. package/esm/auth/client/Auth.js +13 -5
  16. package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +3 -3
  17. package/esm/auth/{Entities.js → client/Entities.js} +30 -14
  18. package/esm/auth/client/index.d.ts +5 -0
  19. package/esm/auth/client/index.js +5 -0
  20. package/esm/auth/helper.d.ts +6 -1
  21. package/esm/auth/helper.js +11 -4
  22. package/esm/auth/index.d.ts +9 -11
  23. package/esm/auth/index.js +74 -70
  24. package/esm/auth/providers/github.js +2 -1
  25. package/esm/auth/providers/index.js +1 -1
  26. package/esm/auth/providers/strava.js +2 -1
  27. package/esm/auth/static/assets/{Page-RIbXHuZG.d.ts → Page-BEFYPjis.d.ts} +1 -1
  28. package/esm/auth/static/assets/{Page-RIbXHuZG.js → Page-BEFYPjis.js} +1 -1
  29. package/esm/auth/static/assets/Page-Cfysx_UV.d.ts +6 -0
  30. package/esm/auth/static/assets/Page-Cfysx_UV.js +18 -0
  31. package/esm/auth/static/assets/{Page-DBWJjlEQ.d.ts → Page-DtgkOCJs.d.ts} +1 -1
  32. package/esm/auth/static/assets/{Page-DBWJjlEQ.js → Page-DtgkOCJs.js} +1 -1
  33. package/esm/auth/static/assets/index-QypqCYwC.d.ts +63 -0
  34. package/esm/auth/static/assets/index-QypqCYwC.js +2 -0
  35. package/esm/auth/static/index.html +1 -1
  36. package/esm/auth/types.d.ts +7 -5
  37. package/esm/bin/cmd.js +28 -14
  38. package/esm/cellsBuildor.d.ts +1 -0
  39. package/esm/cellsBuildor.js +24 -12
  40. package/esm/changeLog/index.d.ts +23 -7
  41. package/esm/changeLog/index.js +24 -18
  42. package/esm/feedback/FeedbackController.d.ts +12 -3
  43. package/esm/feedback/FeedbackController.js +62 -11
  44. package/esm/feedback/index.d.ts +1 -0
  45. package/esm/feedback/ui/DialogIssue.svelte +28 -9
  46. package/esm/feedback/ui/DialogIssues.svelte +7 -2
  47. package/esm/handle/index.d.ts +1 -1
  48. package/esm/index.d.ts +4 -2
  49. package/esm/index.js +1 -1
  50. package/esm/mail/index.js +1 -1
  51. package/esm/mail/templates/DefaultMail.svelte +1 -1
  52. package/esm/ui/Field.svelte +2 -10
  53. package/esm/ui/GridPaginate.svelte +7 -7
  54. package/esm/ui/GridPaginate.svelte.d.ts +1 -1
  55. package/esm/vite/index.js +4 -1
  56. package/package.json +8 -8
  57. package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
  58. package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
  59. package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
  60. package/esm/auth/static/assets/index-qfq98Nyd.js +0 -2
@@ -7,16 +7,18 @@ export type firstlyDataAuth = {
7
7
  ui?: {
8
8
  paths: {
9
9
  base: string;
10
- sign_up: string;
11
- sign_in: string;
12
- forgot_password: string;
13
- reset_password: string;
14
- verify_email: string;
10
+ sign_up: string | false;
11
+ sign_in: string | false;
12
+ forgot_password: string | false;
13
+ reset_password: string | false;
14
+ verify_email: string | false;
15
15
  };
16
16
  strings: {
17
17
  email: string;
18
18
  email_placeholder: string;
19
19
  password: string;
20
+ confirm: string;
21
+ reset: string;
20
22
  btn_sign_in: string;
21
23
  btn_sign_up: string;
22
24
  forgot_password: string;
package/esm/bin/cmd.js CHANGED
@@ -31,22 +31,30 @@ const res = (await p.multiselect({
31
31
  message: 'You can generate different things here',
32
32
  options,
33
33
  }));
34
- const devDependenciesPrepare = {
35
- '@kitql/eslint-config': '0.3.6',
36
- '@kitql/helpers': '0.8.9',
34
+ // devDependencies
35
+ function mergeAndSort(deps, depsToAdd) {
36
+ const prepare = {
37
+ ...depsToAdd,
38
+ ...deps,
39
+ };
40
+ // sort by name
41
+ const sorted = Object.keys(prepare)
42
+ .sort()
43
+ .reduce((acc, key) => {
44
+ acc[key] = prepare[key];
45
+ return acc;
46
+ }, {});
47
+ return sorted;
48
+ }
49
+ pkg.devDependencies = mergeAndSort(pkg.devDependencies, {
50
+ '@kitql/eslint-config': '0.3.7',
51
+ '@kitql/helpers': '0.8.10',
37
52
  pg: '8.12.0',
38
- oslo: '^1.2.0',
39
53
  remult: versionFirstly,
40
- ...pkg.devDependencies,
41
- };
42
- // sort by name
43
- const devDependenciesSorted = Object.keys(devDependenciesPrepare)
44
- .sort()
45
- .reduce((acc, key) => {
46
- acc[key] = devDependenciesPrepare[key];
47
- return acc;
48
- }, {});
49
- pkg.devDependencies = devDependenciesSorted;
54
+ });
55
+ pkg.dependencies = mergeAndSort(pkg.dependencies, {
56
+ oslo: '^1.2.1',
57
+ });
50
58
  pkg.scripts = {
51
59
  ...pkg.scripts,
52
60
  '//// ---- BEST PRACTICES ---- ////': '',
@@ -190,6 +198,12 @@ export const api = firstly({
190
198
  log.success('App is ready! 🚀')
191
199
  },
192
200
  },
201
+
202
+ //----------------------------------------
203
+ // enabling changeLog in general.
204
+ // To enable it, replace @Entity by @FF_Entity in your entities
205
+ //----------------------------------------
206
+ // changeLog(),
193
207
  ],
194
208
  })
195
209
  `,
@@ -41,5 +41,6 @@ export declare function cellBuildor<Entity>(repo: Repository<Entity>, inputBuild
41
41
  export declare const fieldsOf: <Entity>(b: Cell<Entity>[]) => FieldMetadata<any, Entity>[];
42
42
  export declare const getPlaceholder: <Entity>(fields: FieldMetadata<any, Entity>[]) => string;
43
43
  export declare const buildSearchWhere: <Entity>(entity: Entity | undefined, fields: FieldMetadata<any, Entity>[], search?: string | null) => EntityFilter<Entity>[];
44
+ export declare const containsWords: <Entity>(fields: FieldMetadata<any, Entity>[], search: string) => EntityFilter<Entity>;
44
45
  export declare const buildWhere: <Entity>(entity: Entity | undefined, defaultWhere: EntityFilter<Entity> | undefined, fields_filter: FieldMetadata<any, Entity>[], fields_search: FieldMetadata<any, Entity>[], obj: Record<string, string>) => EntityFilter<Entity>;
45
46
  export {};
@@ -55,28 +55,40 @@ export const buildSearchWhere = (entity, fields, search) => {
55
55
  const f = [
56
56
  {
57
57
  $or: fields.map((f) => {
58
- if (f.isServerExpression) {
59
- // check if this field has a specific filter function
60
- const fnName = f.key + 'Filter';
58
+ // REMULT P1: isServerExpression is false when sqlExpression there ?!
59
+ // if (f.isServerExpression || f.options.sqlExpression) {
60
+ // check if this field has a specific filter function
61
+ const fnName = f.key + 'Filter';
62
+ // @ts-ignore
63
+ if (entity && entity[fnName]) {
61
64
  // @ts-ignore
62
- if (entity && entity[fnName]) {
63
- // @ts-ignore
64
- return entity[fnName](search);
65
- }
66
- return {};
65
+ return entity[fnName](search);
67
66
  }
67
+ // let's continue with the default behavior
68
+ // return {}
69
+ // }
68
70
  if (f.inputType === 'number') {
69
71
  return { [f.key]: search };
70
72
  }
71
- const sSplitted = search.split(' ');
72
- return {
73
- $and: sSplitted.map((s) => ({ [f.key]: { $contains: s } })),
74
- };
73
+ return containsWords([f], search);
75
74
  }),
76
75
  },
77
76
  ];
78
77
  return f;
79
78
  };
79
+ export const containsWords = (fields, search) => {
80
+ const sSplitted = search.split(' ');
81
+ if (fields.length === 1) {
82
+ return {
83
+ $and: sSplitted.map((s) => ({ [fields[0].key]: { $contains: s } })),
84
+ };
85
+ }
86
+ return {
87
+ $or: fields.map((f) => {
88
+ return { $and: sSplitted.map((s) => ({ [f.key]: { $contains: s } })) };
89
+ }),
90
+ };
91
+ };
80
92
  export const buildWhere = (entity, defaultWhere, fields_filter, fields_search, obj) => {
81
93
  const and = [];
82
94
  if (defaultWhere) {
@@ -1,12 +1,29 @@
1
1
  import { type FieldRef, type FieldsRef, type LifecycleEvent } from 'remult';
2
2
  import type { Module } from '../api';
3
- export declare class WithChangeLogs {
4
- }
5
3
  /**
6
- * in an entity, add these 2 functions:
4
+ * ## Default way
5
+ * The easiest is to switch from `@Entity` to `@FF_Entity` to the entities where you want to log changes.
6
+ *
7
7
  * ```ts
8
+ * \@FF_Entity<User>('users', {
9
+ *
10
+ * // Optional => To disable change logs
11
+ * // changeLog: false,
12
+ *
13
+ * // Optional => To disable some columns from being logged
14
+ * // changeLog: {
15
+ * // excludeColumns: (e) => {
16
+ * // return [e.password]
17
+ * // },
18
+ * // },
19
+ * })
20
+ * export class User {}
21
+ * ```
8
22
  *
9
- * \@Entity<Task>('tasks', {
23
+ * ## Manual way
24
+ * If you want to go more manual, you can import these functions and call them in your entity's lifecycle events.
25
+ * ```ts
26
+ * \@Entity<User>('users', {
10
27
  * saved: async (entity, e) => {
11
28
  * await recordSaved(entity, e)
12
29
  * },
@@ -14,7 +31,7 @@ export declare class WithChangeLogs {
14
31
  * await recordDeleted(entity, e)
15
32
  * },
16
33
  * })
17
- *
34
+ * export class User {}
18
35
  * ```
19
36
  */
20
37
  export declare const changeLog: () => Module;
@@ -40,7 +57,7 @@ export interface change {
40
57
  }
41
58
  export declare function recordSaved<entityType>(entity: entityType, e: LifecycleEvent<entityType>, options?: ColumnDeciderArgs<entityType>): Promise<void>;
42
59
  export declare function recordDeleted<entityType>(entity: entityType, e: LifecycleEvent<entityType>, options?: ColumnDeciderArgs<entityType>): Promise<void>;
43
- interface ColumnDeciderArgs<entityType> {
60
+ export interface ColumnDeciderArgs<entityType> {
44
61
  excludeColumns?: (e: FieldsRef<entityType>) => FieldRef<entityType, any>[];
45
62
  excludeValues?: (e: FieldsRef<entityType>) => FieldRef<entityType, any>[];
46
63
  forceDate?: Date;
@@ -52,4 +69,3 @@ export declare class FieldDecider<entityType> {
52
69
  excludedValues: FieldRef<entityType>[];
53
70
  constructor(entity: entityType, options?: ColumnDeciderArgs<entityType>);
54
71
  }
55
- export {};
@@ -5,24 +5,30 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { Entity, Fields, getEntityRef, IdEntity, isBackend, remult, } from 'remult';
8
- let WithChangeLogs = class WithChangeLogs {
9
- };
10
- WithChangeLogs = __decorate([
11
- Entity('change_logs', {
12
- saved: async (entity, e) => {
13
- await recordSaved(entity, e);
14
- },
15
- deleted: async (entity, e) => {
16
- await recordDeleted(entity, e);
17
- },
18
- })
19
- ], WithChangeLogs);
20
- export { WithChangeLogs };
21
8
  /**
22
- * in an entity, add these 2 functions:
9
+ * ## Default way
10
+ * The easiest is to switch from `@Entity` to `@FF_Entity` to the entities where you want to log changes.
11
+ *
23
12
  * ```ts
13
+ * \@FF_Entity<User>('users', {
14
+ *
15
+ * // Optional => To disable change logs
16
+ * // changeLog: false,
24
17
  *
25
- * \@Entity<Task>('tasks', {
18
+ * // Optional => To disable some columns from being logged
19
+ * // changeLog: {
20
+ * // excludeColumns: (e) => {
21
+ * // return [e.password]
22
+ * // },
23
+ * // },
24
+ * })
25
+ * export class User {}
26
+ * ```
27
+ *
28
+ * ## Manual way
29
+ * If you want to go more manual, you can import these functions and call them in your entity's lifecycle events.
30
+ * ```ts
31
+ * \@Entity<User>('users', {
26
32
  * saved: async (entity, e) => {
27
33
  * await recordSaved(entity, e)
28
34
  * },
@@ -30,7 +36,7 @@ export { WithChangeLogs };
30
36
  * await recordDeleted(entity, e)
31
37
  * },
32
38
  * })
33
- *
39
+ * export class User {}
34
40
  * ```
35
41
  */
36
42
  export const changeLog = () => {
@@ -74,8 +80,8 @@ __decorate([
74
80
  Fields.boolean()
75
81
  ], ChangeLog.prototype, "deleted", void 0);
76
82
  ChangeLog = __decorate([
77
- Entity('change_logs', {
78
- caption: 'Change Logs',
83
+ Entity('_ff_change_logs', {
84
+ caption: 'FF Change Logs',
79
85
  allowApiCrud: false,
80
86
  defaultOrderBy: {
81
87
  changeDate: 'desc',
@@ -8,7 +8,8 @@ export declare class FeedbackController {
8
8
  id: string;
9
9
  number: number;
10
10
  titleHTML: string;
11
- state: 'OPEN' | 'CLOSED';
11
+ state: string;
12
+ highlight: boolean;
12
13
  }[]>;
13
14
  static getIssue(issueNumber: number): Promise<{
14
15
  id: any;
@@ -19,12 +20,20 @@ export declare class FeedbackController {
19
20
  createdAt: Date;
20
21
  public: boolean;
21
22
  }[];
23
+ labels: any;
24
+ highlight: any;
22
25
  }>;
23
26
  static createIssue(milestoneId: string, title: string, body: string, page: string): Promise<{
24
27
  id: string;
25
28
  number: number;
26
29
  }>;
27
- static addCommentOnIssue(issueId: string, body: string, page: string): Promise<string>;
28
- static close(issueId: string): Promise<string>;
30
+ static addCommentOnIssue(issueId: string, body: string, page: string, labels: {
31
+ id: string;
32
+ name: string;
33
+ }[]): Promise<string>;
34
+ static close(issueId: string, labels: {
35
+ id: string;
36
+ name: string;
37
+ }[]): Promise<string>;
29
38
  static reOpen(issueId: string): Promise<string>;
30
39
  }
@@ -117,6 +117,11 @@ export class FeedbackController {
117
117
  number
118
118
  titleHTML
119
119
  state
120
+ labels(first:10){
121
+ nodes {
122
+ name
123
+ }
124
+ }
120
125
  }
121
126
  }
122
127
  }
@@ -132,7 +137,18 @@ export class FeedbackController {
132
137
  },
133
138
  issueOrder,
134
139
  });
135
- return data.repository.milestone.issues.nodes;
140
+ return data.repository.milestone.issues.nodes.map((issue) => {
141
+ const hasWaitingForAnswerLabel = FEEDBACK_OPTIONS.highlight_label
142
+ ? issue.labels.nodes.some((label) => label.name.includes(FEEDBACK_OPTIONS.highlight_label))
143
+ : false;
144
+ return {
145
+ id: issue.id,
146
+ number: issue.number,
147
+ titleHTML: issue.titleHTML,
148
+ state: issue.state,
149
+ highlight: hasWaitingForAnswerLabel,
150
+ };
151
+ });
136
152
  }
137
153
  static async getIssue(issueNumber) {
138
154
  const data = await getGitHub(`query Issue($repository: String!, $owner: String!, $issueNumber: Int!) {
@@ -142,6 +158,12 @@ export class FeedbackController {
142
158
  createdAt
143
159
  bodyHTML
144
160
  state
161
+ labels(first: 25){
162
+ nodes{
163
+ id
164
+ name
165
+ }
166
+ }
145
167
  comments(first: 100) {
146
168
  nodes {
147
169
  id
@@ -189,10 +211,15 @@ export class FeedbackController {
189
211
  });
190
212
  }
191
213
  }
214
+ const hasWaitingForAnswerLabel = FEEDBACK_OPTIONS.highlight_label
215
+ ? data.repository.issue.labels.nodes.some((label) => label.name.includes(FEEDBACK_OPTIONS.highlight_label))
216
+ : false;
192
217
  const toRet = {
193
218
  id: data.repository.issue.id,
194
219
  state: data.repository.issue.state,
195
220
  items: items.filter((c) => c.public),
221
+ labels: data.repository.issue.labels.nodes,
222
+ highlight: hasWaitingForAnswerLabel,
196
223
  };
197
224
  return toRet;
198
225
  }
@@ -237,39 +264,63 @@ export class FeedbackController {
237
264
  await addMetaData(toRet.id, remult.user?.name, page);
238
265
  return toRet;
239
266
  }
240
- static async addCommentOnIssue(issueId, body, page) {
241
- const input = {
267
+ static async addCommentOnIssue(issueId, body, page, labels) {
268
+ const inputComment = {
242
269
  subjectId: issueId,
243
270
  body,
244
271
  };
245
- await getGitHub(`mutation AddComment($input: AddCommentInput!) {
246
- addComment(input: $input) {
272
+ const inputIssue = {
273
+ id: issueId,
274
+ labelIds: (FEEDBACK_OPTIONS.highlight_label
275
+ ? labels.filter((c) => c.name !== FEEDBACK_OPTIONS.highlight_label)
276
+ : labels).map((c) => c.id),
277
+ };
278
+ await getGitHub(`mutation AddComment($inputComment: AddCommentInput!, $inputIssue: UpdateIssueInput!) {
279
+ addComment(input: $inputComment) {
247
280
  commentEdge {
248
281
  node {
249
282
  id
250
283
  }
251
284
  }
252
285
  }
286
+ updateIssue(input: $inputIssue) {
287
+ issue {
288
+ id
289
+ }
290
+ }
253
291
  }
254
292
  `, {
255
- input,
293
+ inputComment,
294
+ inputIssue,
256
295
  });
257
296
  await addMetaData(issueId, remult.user?.name, page);
258
297
  return 'done';
259
298
  }
260
- static async close(issueId) {
261
- const input = {
299
+ static async close(issueId, labels) {
300
+ const inputClose = {
262
301
  issueId,
263
302
  };
264
- await getGitHub(`mutation CloseIssue($input: CloseIssueInput!) {
265
- closeIssue(input: $input) {
303
+ const inputIssue = {
304
+ id: issueId,
305
+ labelIds: (FEEDBACK_OPTIONS.highlight_label
306
+ ? labels.filter((c) => c.name !== FEEDBACK_OPTIONS.highlight_label)
307
+ : labels).map((c) => c.id),
308
+ };
309
+ await getGitHub(`mutation CloseIssue($inputIssue: UpdateIssueInput!, $inputClose: CloseIssueInput!) {
310
+ updateIssue(input: $inputIssue) {
311
+ issue {
312
+ id
313
+ }
314
+ }
315
+ closeIssue(input: $inputClose) {
266
316
  issue {
267
317
  id
268
318
  }
269
319
  }
270
320
  }
271
321
  `, {
272
- input,
322
+ inputIssue,
323
+ inputClose,
273
324
  });
274
325
  return 'done';
275
326
  }
@@ -12,6 +12,7 @@ type FeedbackOptions = {
12
12
  title_filter?: string;
13
13
  labels_filters?: string[];
14
14
  };
15
+ highlight_label?: string;
15
16
  create_label?: string;
16
17
  };
17
18
  export declare let FEEDBACK_OPTIONS: FeedbackOptions;
@@ -29,22 +29,36 @@ const send = async () => {
29
29
  const result = await FeedbackController.createIssue(milestoneId, title, content, p);
30
30
  issueNumber = result.number;
31
31
  } else {
32
- await FeedbackController.addCommentOnIssue(issue.id, content, p);
32
+ await FeedbackController.addCommentOnIssue(issue.id, content, p, issue.labels);
33
33
  }
34
34
  content = "";
35
35
  await update();
36
+ state = "done";
36
37
  };
37
38
  const close = async () => {
38
39
  state = "loading";
39
- await FeedbackController.close(issue.id);
40
+ await FeedbackController.close(issue.id, issue.labels);
40
41
  content = "";
41
42
  await update();
43
+ state = "done";
42
44
  };
43
45
  const reOpen = async () => {
44
46
  state = "loading";
45
47
  await FeedbackController.reOpen(issue.id);
46
48
  content = "";
47
49
  await update();
50
+ state = "done";
51
+ };
52
+ const disableButton = (issueNumber2, title2, content2) => {
53
+ if (issueNumber2) {
54
+ if (content2?.length > 2) {
55
+ return false;
56
+ }
57
+ }
58
+ if (title2?.length > 2 && content2?.length > 2) {
59
+ return false;
60
+ }
61
+ return true;
48
62
  };
49
63
  </script>
50
64
 
@@ -58,7 +72,7 @@ const reOpen = async () => {
58
72
  <div class="chat {item.who ? 'chat-start' : 'chat-end'}">
59
73
  <div class="avatar chat-image">
60
74
  <div class="w-10 rounded-full">
61
- <div class="h-10 w-10 {item.who ? 'bg-secondary' : 'bg-primary'}"></div>
75
+ <div class="h-10 w-10 {item.who ? 'bg-primary' : 'bg-secondary'}"></div>
62
76
  </div>
63
77
  </div>
64
78
  <div class="chat-header">
@@ -73,7 +87,9 @@ const reOpen = async () => {
73
87
  <!-- <div class="chat-footer opacity-50">Delivered</div> -->
74
88
  </div>
75
89
  {/each}
76
-
90
+ {#if issue?.highlight}
91
+ <span class="badge badge-warning">En attente de réponse de TA part 😉, oui 🫵!</span>
92
+ {/if}
77
93
  {#if issueNumber}
78
94
  <button on:click={update} class="divider"></button>
79
95
  {/if}
@@ -86,16 +102,19 @@ const reOpen = async () => {
86
102
  {#if issueNumber === null}
87
103
  <Field cell={cellBuildor(repo(FilterEntity), 'title')} bind:value={title} />
88
104
  {/if}
89
- <Textarea bind:value={content}></Textarea>
105
+ <Textarea bind:value={content} placeholder="Un peu de détail c'est pas mal... Fais toi Plaiz'"
106
+ ></Textarea>
90
107
  <div class="flex justify-between">
91
108
  {#if issueNumber}
92
- <Button on:click={close} tabIndex={-1} class="btn-outline btn-error"
93
- >Clore le feedback</Button
94
- >
109
+ <Button on:click={close} tabIndex={-1} class="btn-outline btn-error">
110
+ Clore le feedback
111
+ </Button>
95
112
  {:else}
96
113
  <div></div>
97
114
  {/if}
98
- <Button on:click={send} disabled={content?.length < 3}>Envoyer</Button>
115
+ <Button on:click={send} disabled={disableButton(issueNumber, title, content)}>
116
+ Envoyer
117
+ </Button>
99
118
  </div>
100
119
  {/if}
101
120
  {/if}
@@ -75,8 +75,13 @@ onMount(async () => {
75
75
  }}
76
76
  class="btn-neutral"
77
77
  >
78
- <div class="w-full text-left">
79
- {@html issue.titleHTML}
78
+ <div class="flex w-full justify-center justify-items-center text-left">
79
+ <div class="flex-grow">
80
+ {@html issue.titleHTML}
81
+ </div>
82
+ {#if issue.highlight}
83
+ <span class="badge badge-warning">En attente de réponse</span>
84
+ {/if}
80
85
  </div>
81
86
  </Button>
82
87
  {:else}
@@ -1,4 +1,4 @@
1
- /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.1_svelte@4.2.18_vite@5.4.1_@types+node@_vtylvkjv5lewhfcl4vq2py4rce/node_modules/@sveltejs/kit" />
1
+ /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.2_svelte@4.2.18_vite@5.4.1_@types+node@_lnml5jetshdinsnlj53joqxhde/node_modules/@sveltejs/kit" />
2
2
  import type { Handle } from '@sveltejs/kit';
3
3
  import type { RemultSveltekitServer } from 'remult/remult-sveltekit';
4
4
  import type { Module } from '../api';
package/esm/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.1_svelte@4.2.18_vite@5.4.1_@types+node@_vtylvkjv5lewhfcl4vq2py4rce/node_modules/@sveltejs/kit" />
1
+ /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.2_svelte@4.2.18_vite@5.4.1_@types+node@_lnml5jetshdinsnlj53joqxhde/node_modules/@sveltejs/kit" />
2
2
  import type { RequestEvent } from '@sveltejs/kit';
3
3
  import type { FindOptionsBase } from 'remult';
4
4
  import { Log } from '@kitql/helpers';
5
5
  import type { BaseEnum, BaseItem, FF_Icon } from './BaseEnum.js';
6
6
  import type { CellsInput as CellsInput_ForExport } from './cellsBuildor.js';
7
+ import type { ColumnDeciderArgs } from './changeLog/index.js';
7
8
  import { default as DefaultMail } from './mail/templates/DefaultMail.svelte';
8
9
  import { storeItem } from './storeItem.js';
9
10
  import { storeList } from './storeList.js';
@@ -43,7 +44,7 @@ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
43
44
  export { BaseEnum } from './BaseEnum.js';
44
45
  export { dialog } from './ui/dialog/dialog.js';
45
46
  export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getEnums, } from './helper.js';
46
- export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, } from './cellsBuildor.js';
47
+ export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
47
48
  export { storeItem };
48
49
  export { storeList };
49
50
  export { displayPhone, arrToStr } from './formats/strings.js';
@@ -83,6 +84,7 @@ declare module 'remult' {
83
84
  permissionApiInsert?: BaseEnum[] | BaseEnum;
84
85
  permissionApiRead?: BaseEnum[] | BaseEnum;
85
86
  permissionApiUpdate?: BaseEnum[] | BaseEnum;
87
+ changeLog?: false | ColumnDeciderArgs<entityType>;
86
88
  }
87
89
  interface UserInfo {
88
90
  session: {
package/esm/index.js CHANGED
@@ -37,7 +37,7 @@ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
37
37
  export { BaseEnum } from './BaseEnum.js';
38
38
  export { dialog } from './ui/dialog/dialog.js';
39
39
  export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getEnums, } from './helper.js';
40
- export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, } from './cellsBuildor.js';
40
+ export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
41
41
  export { storeItem };
42
42
  export { storeList };
43
43
  export { displayPhone, arrToStr } from './formats/strings.js';
package/esm/mail/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { render } from 'svelte-email';
1
+ import { render } from 'svelty-email';
2
2
  import { cyan, green, Log, magenta, red, sleep, white } from '@kitql/helpers';
3
3
  import { DefaultMail } from '../';
4
4
  const log = new Log('firstly | mail');
@@ -1,4 +1,4 @@
1
- <script>import { Button, Container, Head, Heading, Html, Preview, Section, Text } from "svelte-email";
1
+ <script>import { Button, Container, Head, Heading, Html, Preview, Section, Text } from "svelty-email";
2
2
  export let previewText;
3
3
  export let title;
4
4
  export let sections = [];
@@ -17,6 +17,7 @@ import MultiSelectMelt from "./internals/select/MultiSelectMelt.svelte";
17
17
  import SelectMelt from "./internals/select/SelectMelt.svelte";
18
18
  import SelectRadio from "./internals/select/SelectRadio.svelte";
19
19
  import Textarea from "./internals/Textarea.svelte";
20
+ import LinkPlus from "./link/LinkPlus.svelte";
20
21
  export let cell;
21
22
  export let value = void 0;
22
23
  export let cellsValues = {};
@@ -153,16 +154,7 @@ const calcSuffix = (value2) => {
153
154
  {:else if metaType.kind === 'relation'}
154
155
  {@const item = getEntityDisplayValue(metaType.repoTarget, value)}
155
156
  <div class={tw('flex items-center gap-4', 'h-12', 'pl-2')}>
156
- {#if item && item?.icon}
157
- <Icon {...item.icon} />
158
- {/if}
159
- <div class="grid grid-cols-1">
160
- <span>{cell?.header ?? item?.caption ?? '-'}</span>
161
- <!-- && captionSubStyle === 'inline' -->
162
- {#if item?.captionSub}
163
- <span class="text-base-content/70 text-xs italic">{item.captionSub}</span>
164
- {/if}
165
- </div>
157
+ <LinkPlus {item}></LinkPlus>
166
158
  </div>
167
159
  {:else if metaType.kind === 'enum'}
168
160
  {@const v = displayWithDefaultAndSuffix(cell.field, value)}