From 1f45693c612a8bedb13200529eafd345284f3926 Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Fri, 24 Apr 2026 10:36:28 +0200 Subject: [PATCH 01/13] fix(front): fix duplicate route, cleaning components --- .../front/translations/curriculums/en-us.yaml | 4 ++ .../front/translations/curriculums/fr-fr.yaml | 4 ++ .../src/routes/curriculums/duplicate.route.ts | 6 +- @libs/users-front/src/assets/icons/rename.gts | 16 ----- .../curriculums/curriculum-item.gts | 60 ++++--------------- .../curriculums/curriculum-list.gts | 6 +- .../curriculums/curriculum-validation.ts | 11 ---- 7 files changed, 26 insertions(+), 81 deletions(-) delete mode 100644 @libs/users-front/src/assets/icons/rename.gts diff --git a/@apps/front/translations/curriculums/en-us.yaml b/@apps/front/translations/curriculums/en-us.yaml index 6d150d4..f68e007 100644 --- a/@apps/front/translations/curriculums/en-us.yaml +++ b/@apps/front/translations/curriculums/en-us.yaml @@ -9,6 +9,10 @@ moreActions: download: 'Download' rename: 'Rename' validation: + selectModel: + required: 'A model must be selected' + minimumLength: 'A model must be selected' + maximumLength: 'A model must be selected' titleRequired: 'Title is required' minimumTitleLength: 'Title must be at least 1 character long' maximumTitleLength: 'Title must be at most 255 characters long' diff --git a/@apps/front/translations/curriculums/fr-fr.yaml b/@apps/front/translations/curriculums/fr-fr.yaml index 3529e49..efef3ff 100644 --- a/@apps/front/translations/curriculums/fr-fr.yaml +++ b/@apps/front/translations/curriculums/fr-fr.yaml @@ -9,6 +9,10 @@ moreActions: download: 'Télécharger' rename: 'Renommer' validation: + selectModel: + required: 'Un modèle doit être sélectionné' + minimumLength: 'Un modèle doit être sélectionné' + maximumLength: 'Un modèle doit être sélectionné' titleRequired: 'Le titre est requis' minimumTitleLength: 'Le titre doit comporter au moins 1 caractère' maximumTitleLength: 'Le titre doit comporter au maximum 255 caractères' diff --git a/@libs/users-backend/src/routes/curriculums/duplicate.route.ts b/@libs/users-backend/src/routes/curriculums/duplicate.route.ts index b376d4a..40ea4c1 100644 --- a/@libs/users-backend/src/routes/curriculums/duplicate.route.ts +++ b/@libs/users-backend/src/routes/curriculums/duplicate.route.ts @@ -94,9 +94,9 @@ export class DuplicateCurriculumRoute implements Route { if (fields[fieldType] !== "" && fields[fieldType] !== undefined) { const oldFilePath = fields[fieldType] as string; const fileExtension = oldFilePath.split(".").pop(); - const newFileName = `${newItem.id}.${fileExtension}`; - const newFilePath = `uploads/${newFileName}/${fieldType}`; - + const newFileName = `${newItem.id}-${fieldType}.${fileExtension}`; + const newFilePath = `uploads/${newFileName}`; + await fs.promises.copyFile(oldFilePath, newFilePath); fields[fieldType] = newFilePath; diff --git a/@libs/users-front/src/assets/icons/rename.gts b/@libs/users-front/src/assets/icons/rename.gts deleted file mode 100644 index 80fa07f..0000000 --- a/@libs/users-front/src/assets/icons/rename.gts +++ /dev/null @@ -1,16 +0,0 @@ -import type { TOC } from '@ember/component/template-only'; - -const RenameIcon: TOC<{ Element: SVGSVGElement }> = ; - -export default RenameIcon; diff --git a/@libs/users-front/src/components/curriculums/curriculum-item.gts b/@libs/users-front/src/components/curriculums/curriculum-item.gts index e655f08..997700a 100644 --- a/@libs/users-front/src/components/curriculums/curriculum-item.gts +++ b/@libs/users-front/src/components/curriculums/curriculum-item.gts @@ -6,9 +6,7 @@ import t from 'ember-intl/helpers/t'; import { action } from '@ember/object'; import EditIcon from '#src/assets/icons/edit.gts'; -import RenameIcon from '#src/assets/icons/rename.gts'; import DuplicateIcon from '#src/assets/icons/duplicate.gts'; -import DownloadIcon from '#src/assets/icons/download.gts'; import DeleteIcon from '#src/assets/icons/delete.gts'; import CvIcon from '#src/assets/icons/cv.gts'; @@ -25,12 +23,11 @@ import relativeTime from '#src/helpers/relative-time.ts'; import type ImmerChangeset from 'ember-immer-changeset'; import TpkForm from '@triptyk/ember-input-validation/components/tpk-form'; import { CurriculumChangeset } from '#src/changesets/curriculum.ts'; -import { createCurriculumValidationSchema } from '#src/components/curriculums/curriculum-validation.ts'; +import { editCurriculumValidationSchema } from '#src/components/curriculums/curriculum-validation.ts'; import type { IntlService } from 'ember-intl'; import type Owner from '@ember/owner'; import type { - UpdatedCurriculum, - ValidatedCurriculum, + UpdatedCurriculum } from '#src/components/curriculums/curriculum-validation.ts'; import HandleSaveService from '@libs/shared-front/services/handle-save'; @@ -54,21 +51,14 @@ class CurriculumItem extends Component { @service declare intl: IntlService; @service declare handleSave: HandleSaveService; - validationSchema: ReturnType; + validationSchema: ReturnType; changeset = new CurriculumChangeset({ title: this.args.curriculum.title, }); constructor(owner: Owner, args: CurriculumItemSignature['Args']) { super(owner, args); - this.validationSchema = createCurriculumValidationSchema(this.intl); - } - - @action - async renameOnEnter(event: KeyboardEvent) { - if (event.key === 'Enter') { - await this.rename((event.target as HTMLInputElement).value); - } + this.validationSchema = editCurriculumValidationSchema(this.intl); } @action @@ -94,11 +84,6 @@ class CurriculumItem extends Component { this.args.onRefresh?.(); } - @action - async renameOnBlur(event: FocusEvent) { - await this.rename((event.target as HTMLInputElement).value); - } - @action async rename(title: string) { if (!this.args.curriculum.id || title === this.args.curriculum.title) @@ -107,21 +92,9 @@ class CurriculumItem extends Component { this.args.onRefresh?.(); } - @action - focusTitle() { - const input = document.querySelector( - `input[name="curriculum-title-${this.args.curriculum.id}"]` - ); - - if (input) { - (input as HTMLInputElement).focus(); - (input as HTMLInputElement).select(); - } - } - onSubmit = async ( data: UpdatedCurriculum, - c: ImmerChangeset + c: ImmerChangeset ) => { await this.handleSave.handleSave({ saveAction: async () => await this.rename(data.title), @@ -140,7 +113,7 @@ class CurriculumItem extends Component {
{{#each this.curriculums as |curriculum|}} diff --git a/@libs/users-front/src/components/curriculums/curriculum-validation.ts b/@libs/users-front/src/components/curriculums/curriculum-validation.ts index 80c6363..0baaa1c 100644 --- a/@libs/users-front/src/components/curriculums/curriculum-validation.ts +++ b/@libs/users-front/src/components/curriculums/curriculum-validation.ts @@ -2,13 +2,6 @@ import { object, string } from 'zod'; import type z from 'zod'; import type { IntlService } from 'ember-intl'; -export const createCurriculumValidationSchema = (intl: IntlService) => - object({ - title: string(intl.t('curriculums.validation.titleRequired')) - .min(1, intl.t('curriculums.validation.minimumTitleLength')) - .max(255, intl.t('curriculums.validation.maximumTitleLength')), - }); - export const editCurriculumValidationSchema = (intl: IntlService) => object({ title: string(intl.t('curriculums.validation.titleRequired')) @@ -16,10 +9,6 @@ export const editCurriculumValidationSchema = (intl: IntlService) => .max(255, intl.t('curriculums.validation.maximumTitleLength')), }); -export type ValidatedCurriculum = z.infer< - ReturnType ->; - export type UpdatedCurriculum = z.infer< ReturnType >; From 72f1145817dbadf70f4e84df14e8b6f33a0f6f39 Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Fri, 24 Apr 2026 10:38:11 +0200 Subject: [PATCH 02/13] fix(lint): fix lint tets --- .../src/components/curriculums/curriculum-item.gts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/@libs/users-front/src/components/curriculums/curriculum-item.gts b/@libs/users-front/src/components/curriculums/curriculum-item.gts index 997700a..c3fd78e 100644 --- a/@libs/users-front/src/components/curriculums/curriculum-item.gts +++ b/@libs/users-front/src/components/curriculums/curriculum-item.gts @@ -26,9 +26,7 @@ import { CurriculumChangeset } from '#src/changesets/curriculum.ts'; import { editCurriculumValidationSchema } from '#src/components/curriculums/curriculum-validation.ts'; import type { IntlService } from 'ember-intl'; import type Owner from '@ember/owner'; -import type { - UpdatedCurriculum -} from '#src/components/curriculums/curriculum-validation.ts'; +import type { UpdatedCurriculum } from '#src/components/curriculums/curriculum-validation.ts'; import HandleSaveService from '@libs/shared-front/services/handle-save'; interface CurriculumItemSignature { @@ -152,7 +150,10 @@ class CurriculumItem extends Component { /> - + {{t "curriculums.view.lastModified"}} {{relativeTime @curriculum.updatedAt}} @@ -164,7 +165,9 @@ export default CurriculumItem; export const CurriculumItemPageObject = create({ scope: '[data-test-curriculum-item]', - moreActionsButton: clickable('[data-test-curriculum-item-more-action-button]'), + moreActionsButton: clickable( + '[data-test-curriculum-item-more-action-button]' + ), titleInput: fillable('[data-test-curriculum-item-title] input'), titleValue: value('[data-test-curriculum-item-title]'), lastModified: text('[data-test-curriculum-item-last-modified]'), From f8b5ecdd55ee81a7492a549b7fe9d166003a3c34 Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Fri, 24 Apr 2026 10:39:43 +0200 Subject: [PATCH 03/13] fix(lint): fix lint test --- @libs/users-backend/src/routes/curriculums/duplicate.route.ts | 2 +- .../integration/components/curriculums/curriculum-item-test.gts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/@libs/users-backend/src/routes/curriculums/duplicate.route.ts b/@libs/users-backend/src/routes/curriculums/duplicate.route.ts index 40ea4c1..2316a6b 100644 --- a/@libs/users-backend/src/routes/curriculums/duplicate.route.ts +++ b/@libs/users-backend/src/routes/curriculums/duplicate.route.ts @@ -96,7 +96,7 @@ export class DuplicateCurriculumRoute implements Route { const fileExtension = oldFilePath.split(".").pop(); const newFileName = `${newItem.id}-${fieldType}.${fileExtension}`; const newFilePath = `uploads/${newFileName}`; - + await fs.promises.copyFile(oldFilePath, newFilePath); fields[fieldType] = newFilePath; diff --git a/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts b/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts index 5c5af1a..84dddb1 100644 --- a/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts +++ b/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts @@ -41,7 +41,7 @@ describe('curriculum-item', function () { ); - await CurriculumItemPageObject.enterButton(); + await CurriculumItemPageObject.moreActionsButton(); assert(true, 'Buttons are clickable'); }); From a309afaeb16c58344840aaac6b378f37724208bd Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Fri, 24 Apr 2026 10:45:33 +0200 Subject: [PATCH 04/13] fix(test): fix test --- .../integration/components/curriculums/curriculum-item-test.gts | 1 - 1 file changed, 1 deletion(-) diff --git a/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts b/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts index 84dddb1..46b46c9 100644 --- a/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts +++ b/@libs/users-front/tests/integration/components/curriculums/curriculum-item-test.gts @@ -27,7 +27,6 @@ describe('curriculum-item', function () { ); expect(CurriculumItemPageObject.titleInput).toBeDefined(); - expect(CurriculumItemPageObject.enterButton).toBeDefined(); expect(CurriculumItemPageObject.moreActionsButton).toBeDefined(); } ); From 4e47832f10158f85b32c6db58a2363294cab28c2 Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Mon, 27 Apr 2026 10:51:31 +0200 Subject: [PATCH 05/13] fix(front): cleaning css, add update preview --- .../backend/src/templates/template1/style.css | 24 ++++--------------- .../backend/src/templates/template2/style.css | 13 ---------- .../curriculums/edit/curriculum-edit-view.gts | 5 ++-- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/@apps/backend/src/templates/template1/style.css b/@apps/backend/src/templates/template1/style.css index e2aa2d1..bbe6526 100644 --- a/@apps/backend/src/templates/template1/style.css +++ b/@apps/backend/src/templates/template1/style.css @@ -11,11 +11,10 @@ @page { size: A4 portrait; - margin: 0; /* On gère les marges en CSS pour le fond perdu */ + margin: 0; } html { - /* L'astuce cruciale : Le fond est dessiné sur toute la hauteur du doc */ background: linear-gradient(to right, #1a2e4a 0%, #1a2e4a 72mm, #ffffff 72mm, #ffffff 100%); -webkit-print-color-adjust: exact; print-color-adjust: exact; @@ -26,8 +25,8 @@ body { font-size: 10pt; line-height: 1.5; color: #2d2d2d; - background: transparent; /* Laisse voir le fond du html */ - padding: 15mm 0; /* Simule les marges haut/bas sur chaque page */ + background: transparent; + padding: 15mm 0; } /* ── Structure ────────────────────────────────────────── */ @@ -41,7 +40,7 @@ body { /* ── Sidebar ──────────────────────────────────────────── */ .cv__sidebar { color: #ecf0f1; - padding: 0 7mm 10mm 7mm; /* Marge haut gérée par le body */ + padding: 0 7mm 10mm 7mm; display: flex; flex-direction: column; gap: 8mm; @@ -49,7 +48,7 @@ body { /* ── Main ─────────────────────────────────────────────── */ .cv__main { - padding: 0 10mm 10mm 8mm; /* Marge haut gérée par le body */ + padding: 0 10mm 10mm 8mm; display: flex; flex-direction: column; gap: 7mm; @@ -219,16 +218,3 @@ body { padding: 1mm 2.5mm; border-radius: 1mm; } - -/* ── Ajustements spécifiques pour l'écran (Preview) ─── */ -@media screen { - body { - background: #e0e0e0; - padding: 20px; - } - .cv { - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); - min-height: 297mm; - background: white; /* Pour la préview écran */ - } -} diff --git a/@apps/backend/src/templates/template2/style.css b/@apps/backend/src/templates/template2/style.css index 2ad7461..b7cc7c5 100644 --- a/@apps/backend/src/templates/template2/style.css +++ b/@apps/backend/src/templates/template2/style.css @@ -218,16 +218,3 @@ body { padding: 1mm 2.5mm; border-radius: 1mm; } - -/* ── Ajustements spécifiques pour l'écran (Preview) ─── */ -@media screen { - body { - background: #e8e0f0; - padding: 20px; - } - .cv { - box-shadow: 0 10px 30px rgba(45, 27, 78, 0.25); - min-height: 297mm; - background: white; - } -} diff --git a/@libs/users-front/src/components/curriculums/edit/curriculum-edit-view.gts b/@libs/users-front/src/components/curriculums/edit/curriculum-edit-view.gts index 250413f..6daa482 100644 --- a/@libs/users-front/src/components/curriculums/edit/curriculum-edit-view.gts +++ b/@libs/users-front/src/components/curriculums/edit/curriculum-edit-view.gts @@ -64,7 +64,7 @@ class CurriculumEditView extends Component { const sectionId = this.getSectionIdByTemplate(templateId, this.sections); if (!sectionId) return; await this.curriculum.createItem(this.args.curriculumId, sectionId); - await this.loadSections(); + this.args.onUpdate(); }; getItemsByTemplate(templateId: string | null, sections: Sections[]) { @@ -82,7 +82,7 @@ class CurriculumEditView extends Component { const sectionId = this.getSectionIdByTemplate(templateId, this.sections); if (!sectionId) return; await this.curriculum.deleteItem(this.args.curriculumId, sectionId, itemId); - await this.loadSections(); + this.args.onUpdate(); }; onDeleteSection = async (templateId: string | null) => { @@ -159,7 +159,6 @@ class CurriculumEditView extends Component { this.dragSourceItemIndex = null; this.dragSourceTemplateId = null; - await this.loadSections(); this.args.onUpdate(); } From cba53b9b0f044da96d1f6fb0d471e237ae640d3a Mon Sep 17 00:00:00 2001 From: jean bourgies Date: Mon, 27 Apr 2026 15:30:20 +0200 Subject: [PATCH 06/13] feat(common-ui): add dynamix common-ui, changeset, validation schemas --- .../src/seeders/curriculumInjector.seeder.ts | 38 +++--- .../front/translations/curriculums/en-us.yaml | 1 + .../front/translations/curriculums/fr-fr.yaml | 1 + @libs/users-front/package.json | 3 + .../edit/curriculum-edit-section-item.gts | 117 ++++++------------ .../edit/dynamic-section-item-form.gts | 103 +++++++++++++++ .../src/helpers/schema-field-map.ts | 20 +++ .../src/helpers/schema-to-changeset.ts | 64 ++++++++++ 8 files changed, 247 insertions(+), 100 deletions(-) create mode 100644 @libs/users-front/src/components/curriculums/edit/dynamic-section-item-form.gts create mode 100644 @libs/users-front/src/helpers/schema-field-map.ts create mode 100644 @libs/users-front/src/helpers/schema-to-changeset.ts diff --git a/@apps/backend/src/seeders/curriculumInjector.seeder.ts b/@apps/backend/src/seeders/curriculumInjector.seeder.ts index f58b686..745d6c2 100644 --- a/@apps/backend/src/seeders/curriculumInjector.seeder.ts +++ b/@apps/backend/src/seeders/curriculumInjector.seeder.ts @@ -74,8 +74,8 @@ export default function curriculumInjectorSeeder(em: EntityManager) { id: "e2e-c1", userId: "e2e-login-user", title: "CV Complet - Amaury Deflorenne", - createdAt: new Date("2025-06-01"), - updatedAt: new Date("2025-06-01"), + createdAt: new Date("01/06/2025"), + updatedAt: new Date("01/06/2025"), }) as CurriculumEntityType; const c1Perso = createSection( @@ -107,7 +107,7 @@ export default function curriculumInjectorSeeder(em: EntityManager) { firstName: "Amaury", lastName: "Deflorenne", email: "amaury@gmail.com", - phone: "0601020304", + phone: "+32601020304", address: "123 rue de la paix, 75000 Paris", }); createItem(em, "e2e-c1-s2-profil-i1", c1Profil, 0, { @@ -118,7 +118,7 @@ export default function curriculumInjectorSeeder(em: EntityManager) { employer: "Triptyk", position: "Développeur Fullstack", city: "Lyon", - startDate: "2022-03-01", + startDate: "01/03/2022", endDate: "", description: "Développement d'applications web avec Ember.js et Node.js. Mise en place d'architectures microservices.", @@ -127,8 +127,8 @@ export default function curriculumInjectorSeeder(em: EntityManager) { employer: "WebAgency", position: "Développeur Frontend", city: "Paris", - startDate: "2020-06-01", - endDate: "2022-02-28", + startDate: "01/06/2020", + endDate: "28/02/2022", description: "Intégration et développement d'interfaces React. Optimisation des performances frontend.", }); @@ -136,8 +136,8 @@ export default function curriculumInjectorSeeder(em: EntityManager) { employer: "StartupX", position: "Stagiaire Développeur", city: "Lyon", - startDate: "2019-01-01", - endDate: "2019-12-31", + startDate: "01/01/2019", + endDate: "31/12/2019", description: "Stage de fin d'études axé sur le développement d'une application mobile en React Native.", }); @@ -145,8 +145,8 @@ export default function curriculumInjectorSeeder(em: EntityManager) { employer: "Freelance", position: "Développeur Web", city: "Lyon", - startDate: "2018-01-01", - endDate: "2018-12-31", + startDate: "01/01/2018", + endDate: "31/12/2018", description: "Réalisation de plusieurs projets web pour des clients locaux, principalement en JavaScript.", }); @@ -154,8 +154,8 @@ export default function curriculumInjectorSeeder(em: EntityManager) { employer: "Université de Lyon", position: "Assistant de Recherche", city: "Lyon", - startDate: "2017-01-01", - endDate: "2017-12-31", + startDate: "01/01/2017", + endDate: "31/12/2017", description: "Participation à un projet de recherche sur les systèmes distribués. Publication d'un article dans une conférence internationale.", }); @@ -163,24 +163,24 @@ export default function curriculumInjectorSeeder(em: EntityManager) { school: "Université de Lyon", degree: "Master Informatique", field: "Génie Logiciel", - startDate: "2018-09-01", - endDate: "2020-06-30", + startDate: "01/09/2018", + endDate: "30/06/2020", description: "Spécialisation en architecture logicielle et développement web.", }); createItem(em, "e2e-c1-s4-form-i2", c1Form, 1, { school: "Université de Paris", degree: "Licence Informatique", field: "Informatique", - startDate: "2015-09-01", - endDate: "2018-06-30", + startDate: "01/09/2015", + endDate: "30/06/2018", description: "Formation généraliste en informatique.", }); createItem(em, "e2e-c1-s4-form-i3", c1Form, 2, { school: "Lycée Jean Moulin", degree: "Baccalauréat Scientifique", field: "Sciences de l'ingénieur", - startDate: "2012-09-01", - endDate: "2015-06-30", + startDate: "01/09/2012", + endDate: "30/06/2015", description: "Mention Bien.", }); createItem(em, "e2e-c1-s5-comp-i1", c1Comp, 0, { competence: "TypeScript", level: "Expert" }); @@ -194,7 +194,7 @@ export default function curriculumInjectorSeeder(em: EntityManager) { name: "Jean Dupont", entreprise: "Triptyk", email: "jean.dupont@triptyk.eu", - phone: "0612345678", + phone: "+32612345678", city: "Lyon", }); } diff --git a/@apps/front/translations/curriculums/en-us.yaml b/@apps/front/translations/curriculums/en-us.yaml index f68e007..aafdc73 100644 --- a/@apps/front/translations/curriculums/en-us.yaml +++ b/@apps/front/translations/curriculums/en-us.yaml @@ -30,3 +30,4 @@ edit: noTitle: 'Untitled' selectTemplate: 'Select a template' chooseFile: 'Choose a file' + saveItem: 'Save' diff --git a/@apps/front/translations/curriculums/fr-fr.yaml b/@apps/front/translations/curriculums/fr-fr.yaml index efef3ff..03e691f 100644 --- a/@apps/front/translations/curriculums/fr-fr.yaml +++ b/@apps/front/translations/curriculums/fr-fr.yaml @@ -30,3 +30,4 @@ edit: noTitle: 'Sans titre' selectTemplate: 'Sélectionnez un modèle' chooseFile: 'Choisir un fichier' + saveItem: 'Enregistrer' diff --git a/@libs/users-front/package.json b/@libs/users-front/package.json index 4cc8ded..df97ed5 100644 --- a/@libs/users-front/package.json +++ b/@libs/users-front/package.json @@ -148,11 +148,14 @@ "type": "addon", "main": "addon-main.cjs", "app-js": { + "./components/curriculums/edit/dynamic-section-item-form.js": "./dist/_app_/components/curriculums/edit/dynamic-section-item-form.js", "./components/forms/login-form.js": "./dist/_app_/components/forms/login-form.js", "./components/forms/user-form.js": "./dist/_app_/components/forms/user-form.js", "./handlers/auth.js": "./dist/_app_/handlers/auth.js", "./helpers/cv-renderer.js": "./dist/_app_/helpers/cv-renderer.js", "./helpers/relative-time.js": "./dist/_app_/helpers/relative-time.js", + "./helpers/schema-field-map.js": "./dist/_app_/helpers/schema-field-map.js", + "./helpers/schema-to-changeset.js": "./dist/_app_/helpers/schema-to-changeset.js", "./routes/dashboard/curriculums/edit.js": "./dist/_app_/routes/dashboard/curriculums/edit.js", "./routes/dashboard/curriculums/index.js": "./dist/_app_/routes/dashboard/curriculums/index.js", "./routes/dashboard/users/create.js": "./dist/_app_/routes/dashboard/users/create.js", diff --git a/@libs/users-front/src/components/curriculums/edit/curriculum-edit-section-item.gts b/@libs/users-front/src/components/curriculums/edit/curriculum-edit-section-item.gts index 8fe6954..a946761 100644 --- a/@libs/users-front/src/components/curriculums/edit/curriculum-edit-section-item.gts +++ b/@libs/users-front/src/components/curriculums/edit/curriculum-edit-section-item.gts @@ -2,12 +2,11 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; import { tracked } from '@glimmer/tracking'; import { on } from '@ember/modifier'; -import { get } from '@ember/helper'; import type { SchemaField } from '#src/schemas/section-templates.ts'; -import { fn } from '@ember/helper'; import { service } from '@ember/service'; import type CurriculumService from '#src/services/curriculum.ts'; -import { t, type IntlService } from 'ember-intl'; +import { type IntlService } from 'ember-intl'; +import DynamicSectionForm from '#src/components/curriculums/edit/dynamic-section-item-form.gts'; interface CurriculumEditSectionItemSignature { Element: HTMLDivElement; @@ -25,9 +24,6 @@ interface CurriculumEditSectionItemSignature { }; } -const isTextarea = (field: SchemaField) => field.type === 'textarea'; -const isFileInput = (field: SchemaField) => field.type === 'file'; - class CurriculumEditSectionItem extends Component { @service declare curriculum: CurriculumService; @service declare intl: IntlService; @@ -40,31 +36,6 @@ class CurriculumEditSectionItem extends Component 0) { - const file = input.files[0]; - await this.curriculum.uploadFile( - this.args.curriculumId, - this.args.sectionId!, - this.args.itemId, - file! - ); - this.args.onUpdate(); - return; - } - - await this.curriculum.updateItem( - this.args.curriculumId, - this.args.sectionId!, - this.args.itemId, - { [key]: input.value } - ); - this.args.onUpdate(); - } - @action async uploadFile(key: string, event: Event) { if (key !== 'profilePicture') return; @@ -126,6 +97,33 @@ class CurriculumEditSectionItem extends Component) { + for (const [, value] of Object.entries(data)) { + if (value instanceof File) { + await this.curriculum.uploadFile( + this.args.curriculumId, + this.args.sectionId!, + this.args.itemId, + value + ); + } + } + + const stringData = Object.fromEntries( + Object.entries(data).filter(([, v]) => typeof v === 'string') + ) as Record; + + await this.curriculum.updateItem( + this.args.curriculumId, + this.args.sectionId!, + this.args.itemId, + stringData + ); + + this.args.onUpdate(); + } +