firstly 0.0.7 → 0.0.9

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 (70) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/esm/BaseEnum.d.ts +2 -13
  3. package/esm/BaseEnum.js +0 -4
  4. package/esm/FF_Entity.js +20 -4
  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 +4 -4
  8. package/esm/api/index.js +13 -13
  9. package/esm/auth/Adapter.js +1 -9
  10. package/esm/auth/AuthController.server.d.ts +1 -2
  11. package/esm/auth/AuthController.server.js +21 -12
  12. package/esm/auth/RoleHelpers.d.ts +2 -2
  13. package/esm/auth/RoleHelpers.js +6 -4
  14. package/esm/auth/client/Auth.d.ts +11 -4
  15. package/esm/auth/client/Auth.js +14 -6
  16. package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +4 -4
  17. package/esm/auth/{Entities.js → client/Entities.js} +33 -17
  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 +11 -11
  23. package/esm/auth/index.js +93 -78
  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 +5 -4
  39. package/esm/cellsBuildor.js +42 -17
  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 -13
  44. package/esm/feedback/index.d.ts +1 -0
  45. package/esm/feedback/ui/DialogIssue.svelte +26 -7
  46. package/esm/feedback/ui/DialogIssues.svelte +7 -2
  47. package/esm/handle/index.d.ts +1 -1
  48. package/esm/helper.js +3 -2
  49. package/esm/index.d.ts +10 -3
  50. package/esm/index.js +1 -1
  51. package/esm/mail/index.js +15 -10
  52. package/esm/storeList.d.ts +3 -1
  53. package/esm/storeList.js +20 -10
  54. package/esm/ui/Field.svelte +11 -13
  55. package/esm/ui/FieldGroup.svelte +4 -2
  56. package/esm/ui/Grid.svelte +90 -20
  57. package/esm/ui/Grid.svelte.d.ts +1 -0
  58. package/esm/ui/GridPaginate.svelte +12 -10
  59. package/esm/ui/GridPaginate.svelte.d.ts +1 -1
  60. package/esm/ui/dialog/DialogPrimitive.svelte +1 -5
  61. package/esm/ui/dialog/dialog.d.ts +10 -8
  62. package/esm/ui/dialog/dialog.js +9 -10
  63. package/esm/ui/internals/Input.svelte +10 -1
  64. package/esm/ui/link/LinkPlus.svelte +41 -29
  65. package/esm/vite/index.js +4 -1
  66. package/package.json +8 -8
  67. package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
  68. package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
  69. package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
  70. 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
  `,
@@ -1,10 +1,10 @@
1
1
  import type { SvelteComponent } from 'svelte';
2
- import { type EntityFilter, type FieldMetadata, type Repository } from 'remult';
2
+ import { type ClassType, type EntityFilter, type FieldMetadata, type Repository } from 'remult';
3
3
  import type { UnArray } from './utils/types.js';
4
4
  export type VisibilityMode = 'view' | 'edit' | 'hide';
5
5
  type CellInternal<Entity> = {
6
6
  col?: keyof Entity;
7
- kind?: 'field' | 'field_link' | 'entity_link' | 'slot' | 'header' | 'component';
7
+ kind?: 'field' | 'field_link' | 'entity_link' | 'slot' | 'header' | 'component' | 'baseItem';
8
8
  class?: string;
9
9
  header?: string;
10
10
  headerSlot?: boolean;
@@ -40,6 +40,7 @@ export declare function cellsBuildor<Entity>(repo: Repository<Entity>, inputBuil
40
40
  export declare function cellBuildor<Entity>(repo: Repository<Entity>, inputBuildor: UnArray<CellsInput<Entity>>): Cell<Entity>;
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
- export declare const buildSearchWhere: <Entity>(entity: Entity | undefined, fields: FieldMetadata<any, Entity>[], search?: string | null) => EntityFilter<Entity>[];
44
- 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>;
43
+ export declare const buildSearchWhere: <Entity>(entity: ClassType<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>;
45
+ export declare const buildWhere: <Entity>(entity: ClassType<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(' ').filter((s) => s.length > 0);
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) {
@@ -94,12 +106,25 @@ export const buildWhere = (entity, defaultWhere, fields_filter, fields_search, o
94
106
  and.push({ [field.key]: obj[field.key] });
95
107
  }
96
108
  else if (field.inputType === 'selectEnum') {
109
+ const fnName = field.key + 'Filter';
97
110
  // @ts-ignore
98
- const theEnum = getEnum(field, obj[field.key]);
99
- // Take the where of the enum if it exists, or it's using this selection as a filter
100
- const wheretoUse = theEnum?.where ?? new BaseEnum(obj[field.key]);
101
- // @ts-ignore
102
- and.push({ [field.key]: wheretoUse });
111
+ if (entity && entity[fnName]) {
112
+ // @ts-ignore
113
+ and.push(entity[fnName](obj[field.key]));
114
+ }
115
+ else {
116
+ // @ts-ignore
117
+ const theEnum = getEnum(field, obj[field.key]);
118
+ // Take the where of the enum if it exists, or it's using this selection as a filter
119
+ if (theEnum?.where) {
120
+ and.push(theEnum.where);
121
+ }
122
+ else {
123
+ const wheretoUse = theEnum?.where ?? new BaseEnum(obj[field.key]);
124
+ // @ts-ignore
125
+ and.push({ [field.key]: wheretoUse });
126
+ }
127
+ }
103
128
  }
104
129
  else if (rfi?.type === 'toOne') {
105
130
  // @ts-ignore (setting the id of the relation)
@@ -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
  }
@@ -21,13 +21,11 @@ async function getGitHub(query, variables) {
21
21
  const response = await fetch(GITHUB_GRAPHQL_ENDPOINT, { method: 'POST', headers, body });
22
22
  const result = await response.json();
23
23
  if (result.errors) {
24
- /* eslint-disable */
25
24
  console.error(`result ERRORS`, body, stry(result));
26
25
  }
27
26
  return result.data;
28
27
  }
29
28
  catch (error) {
30
- /* eslint-disable */
31
29
  console.error(`error`, error);
32
30
  }
33
31
  return null;
@@ -117,6 +115,11 @@ export class FeedbackController {
117
115
  number
118
116
  titleHTML
119
117
  state
118
+ labels(first:10){
119
+ nodes {
120
+ name
121
+ }
122
+ }
120
123
  }
121
124
  }
122
125
  }
@@ -132,7 +135,18 @@ export class FeedbackController {
132
135
  },
133
136
  issueOrder,
134
137
  });
135
- return data.repository.milestone.issues.nodes;
138
+ return data.repository.milestone.issues.nodes.map((issue) => {
139
+ const hasWaitingForAnswerLabel = FEEDBACK_OPTIONS.highlight_label
140
+ ? issue.labels.nodes.some((label) => label.name.includes(FEEDBACK_OPTIONS.highlight_label))
141
+ : false;
142
+ return {
143
+ id: issue.id,
144
+ number: issue.number,
145
+ titleHTML: issue.titleHTML,
146
+ state: issue.state,
147
+ highlight: hasWaitingForAnswerLabel,
148
+ };
149
+ });
136
150
  }
137
151
  static async getIssue(issueNumber) {
138
152
  const data = await getGitHub(`query Issue($repository: String!, $owner: String!, $issueNumber: Int!) {
@@ -142,6 +156,12 @@ export class FeedbackController {
142
156
  createdAt
143
157
  bodyHTML
144
158
  state
159
+ labels(first: 25){
160
+ nodes{
161
+ id
162
+ name
163
+ }
164
+ }
145
165
  comments(first: 100) {
146
166
  nodes {
147
167
  id
@@ -189,10 +209,15 @@ export class FeedbackController {
189
209
  });
190
210
  }
191
211
  }
212
+ const hasWaitingForAnswerLabel = FEEDBACK_OPTIONS.highlight_label
213
+ ? data.repository.issue.labels.nodes.some((label) => label.name.includes(FEEDBACK_OPTIONS.highlight_label))
214
+ : false;
192
215
  const toRet = {
193
216
  id: data.repository.issue.id,
194
217
  state: data.repository.issue.state,
195
218
  items: items.filter((c) => c.public),
219
+ labels: data.repository.issue.labels.nodes,
220
+ highlight: hasWaitingForAnswerLabel,
196
221
  };
197
222
  return toRet;
198
223
  }
@@ -237,39 +262,63 @@ export class FeedbackController {
237
262
  await addMetaData(toRet.id, remult.user?.name, page);
238
263
  return toRet;
239
264
  }
240
- static async addCommentOnIssue(issueId, body, page) {
241
- const input = {
265
+ static async addCommentOnIssue(issueId, body, page, labels) {
266
+ const inputComment = {
242
267
  subjectId: issueId,
243
268
  body,
244
269
  };
245
- await getGitHub(`mutation AddComment($input: AddCommentInput!) {
246
- addComment(input: $input) {
270
+ const inputIssue = {
271
+ id: issueId,
272
+ labelIds: (FEEDBACK_OPTIONS.highlight_label
273
+ ? labels.filter((c) => c.name !== FEEDBACK_OPTIONS.highlight_label)
274
+ : labels).map((c) => c.id),
275
+ };
276
+ await getGitHub(`mutation AddComment($inputComment: AddCommentInput!, $inputIssue: UpdateIssueInput!) {
277
+ addComment(input: $inputComment) {
247
278
  commentEdge {
248
279
  node {
249
280
  id
250
281
  }
251
282
  }
252
283
  }
284
+ updateIssue(input: $inputIssue) {
285
+ issue {
286
+ id
287
+ }
288
+ }
253
289
  }
254
290
  `, {
255
- input,
291
+ inputComment,
292
+ inputIssue,
256
293
  });
257
294
  await addMetaData(issueId, remult.user?.name, page);
258
295
  return 'done';
259
296
  }
260
- static async close(issueId) {
261
- const input = {
297
+ static async close(issueId, labels) {
298
+ const inputClose = {
262
299
  issueId,
263
300
  };
264
- await getGitHub(`mutation CloseIssue($input: CloseIssueInput!) {
265
- closeIssue(input: $input) {
301
+ const inputIssue = {
302
+ id: issueId,
303
+ labelIds: (FEEDBACK_OPTIONS.highlight_label
304
+ ? labels.filter((c) => c.name !== FEEDBACK_OPTIONS.highlight_label)
305
+ : labels).map((c) => c.id),
306
+ };
307
+ await getGitHub(`mutation CloseIssue($inputIssue: UpdateIssueInput!, $inputClose: CloseIssueInput!) {
308
+ updateIssue(input: $inputIssue) {
309
+ issue {
310
+ id
311
+ }
312
+ }
313
+ closeIssue(input: $inputClose) {
266
314
  issue {
267
315
  id
268
316
  }
269
317
  }
270
318
  }
271
319
  `, {
272
- input,
320
+ inputIssue,
321
+ inputClose,
273
322
  });
274
323
  return 'done';
275
324
  }
@@ -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">
@@ -69,11 +83,13 @@ const reOpen = async () => {
69
83
  ).toLocaleTimeString()}</time
70
84
  >
71
85
  </div>
72
- <div class="chat-bubble">{@html item.bodyHTML}</div>
86
+ <div class="chat-bubble prose">{@html item.bodyHTML}</div>
73
87
  <!-- <div class="chat-footer opacity-50">Delivered</div> -->
74
88
  </div>
75
89
  {/each}
76
-
90
+ {#if issue?.highlight && issue.state === 'OPEN'}
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,7 +102,8 @@ 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
109
  <Button on:click={close} tabIndex={-1} class="btn-outline btn-error"
@@ -95,7 +112,9 @@ const reOpen = async () => {
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</Button
117
+ >
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/helper.js CHANGED
@@ -22,7 +22,8 @@ export const getEntityDisplayValue = (repo, row) => {
22
22
  }
23
23
  const field = getFirstInterestingField(repo);
24
24
  // REMULT P3 JYC: If it's an enum, it's not working...
25
- return { caption: row ? field.displayValue(row) : '-', id: '' };
25
+ // @ts-ignore (added for row?.id)
26
+ return { caption: row ? field.displayValue(row) : '-', id: row?.id ? row.id : '' };
26
27
  };
27
28
  export const getFieldLinkDisplayValue = (field, row) => {
28
29
  const caption = field.displayValue(row);
@@ -89,7 +90,7 @@ export const displayWithDefaultAndSuffix = (field, value) => {
89
90
  }
90
91
  else {
91
92
  // toRet.push(value ?? '-')
92
- toRet.push(field?.displayValue ? field?.displayValue({ [field.key]: value }) : value ?? '-');
93
+ toRet.push(field?.displayValue ? field?.displayValue({ [field.key]: value }) : (value ?? '-'));
93
94
  }
94
95
  if (value === undefined || value === null) {
95
96
  return '';