Skip to content

Commit

Permalink
Fix Ember Data models relationships
Browse files Browse the repository at this point in the history
Co-authored-by: Iris Benoit-Martin <iris.benoit-martin@pix.fr>
Co-authored-by: Jérémie Jadé <jeremie.jade@pix.fr>
  • Loading branch information
3 people committed Sep 19, 2024
1 parent 43455b6 commit 0ba93e4
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 73 deletions.
4 changes: 2 additions & 2 deletions pix-editor/app/components/pop-in/select-location.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class PopinSelectLocation extends Component {

get competences() {
const framework = this.selectedFramework.data;
const areas = framework.areas;
const areas = framework.hasMany('areas').value() ?? [];
const areaCompetences = areas.map((area) => area.sortedCompetences);
return areaCompetences.reduce((table, competences) => {
return table.concat(competences);
Expand Down Expand Up @@ -155,7 +155,7 @@ export default class PopinSelectLocation extends Component {
if (this._selectedTube) {
return this._selectedTube;
}
return this.tubeList.find((item) => (item.data == this.args.tube.content));
return this.tubeList.find((item) => (item.data == this.args.tube?.content));
}

set selectedTube(value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default class LocalizedController extends Controller {
@action
setUrlsToConsult(value) {
const invalidUrls = [];
let values = value.split('\n').map((s)=>s.trim());
let values = value.split('\n').map((s) => s.trim());
values = values.filter((value) => {
try {
new URL(value);
Expand Down Expand Up @@ -337,7 +337,7 @@ export default class LocalizedController extends Controller {
async _saveAttachments(challenge) {
await challenge.files;

for (const file of challenge.files.toArray()) {
for (const file of challenge.hasMany('files').value()) {
await file.save();
}
for (const file of this.deletedFiles) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class SingleController extends Controller {
deletedFiles = [];
@controller('authenticated.competence')
parentController;
parentController;
get maximized() {
return this.parentController.leftMaximized;
Expand Down Expand Up @@ -105,7 +105,7 @@ export default class SingleController extends Controller {
}
get airtableUrl() {
return `${this.config.airtableUrl}${this.config.airtableBase}/${this.config.tableChallenges}/${ this.challenge.airtableId}`;
return `${this.config.airtableUrl}${this.config.airtableBase}/${this.config.tableChallenges}/${this.challenge.airtableId}`;
}
get lastUpdatedAtISO() {
Expand Down Expand Up @@ -271,7 +271,8 @@ export default class SingleController extends Controller {
this._errorMessage('Erreur lors de la mise en production');
} finally {
this.loader.stop();
}});
}
});
} catch {
this._message('Mise en production abandonnée');
}
Expand Down Expand Up @@ -440,7 +441,7 @@ export default class SingleController extends Controller {
@action
setUrlsToConsult(value) {
const invalidUrls = [];
let values = value.split('\n').map((s)=>s.trim());
let values = value.split('\n').map((s) => s.trim());
values = values.filter((value) => {
try {
new URL(value);
Expand Down Expand Up @@ -682,7 +683,7 @@ export default class SingleController extends Controller {

async _saveAttachments(challenge) {
await challenge.files;
for (const file of challenge.files.toArray()) {
for (const file of challenge.hasMany('files').value()) {
if (file.cloneBeforeSave) {
file.url = await this.storage.cloneFile(file.url);
file.cloneBeforeSave = false;
Expand Down
12 changes: 8 additions & 4 deletions pix-editor/app/models/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ export default class AreaModel extends Model {
@attr titleEnUs;
@attr() code;

@hasMany('competence') competences;
@belongsTo('framework') framework;
@hasMany('competence', { async: true, inverse: 'area' }) competences;
@belongsTo('framework', { async: true, inverse: 'areas' }) framework;

get sortedCompetences() {
return this.competences
.toArray()
const competences = this.hasMany('competences').value();

if (competences === null) return [];

return competences
.slice()
.sort((competenceA, competenceB) => {
const [domainCodeA, competenceCodeA] = competenceA.code.split('.');
const [domainCodeB, competenceCodeB] = competenceB.code.split('.');
Expand Down
4 changes: 2 additions & 2 deletions pix-editor/app/models/attachment.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export default class Attachment extends Model {

@tracked cloneBeforeSave;

@belongsTo('challenge', { inverse: 'files' }) challenge;
@belongsTo('localized-challenge', { inverse: 'files' }) localizedChallenge;
@belongsTo('challenge', { async: true, inverse: 'files' }) challenge;
@belongsTo('localized-challenge', { async: true, inverse: 'files' }) localizedChallenge;
}
15 changes: 9 additions & 6 deletions pix-editor/app/models/challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ export default class ChallengeModel extends Model {
@attr('boolean') shuffled;
@attr({ defaultValue: function() { return []; } }) contextualizedFields;

@belongsTo('skill') skill;
@hasMany('attachment', { inverse: 'challenge' }) files;
@hasMany('localized-challenge', { inverse: 'challenge' }) localizedChallenges;
@belongsTo('skill', { inverse: 'challenges', async: true }) skill;
@hasMany('attachment', { inverse: 'challenge', async: true }) files;
@hasMany('localized-challenge', { inverse: 'challenge', async: true }) localizedChallenges;

@service('store') myStore;
@service config;
Expand All @@ -56,11 +56,13 @@ export default class ChallengeModel extends Model {
@tracked _definedBaseName;

get illustration() {
return this.files.find((file) => file.type === 'illustration' && !file.isDeleted);
const files = this.hasMany('files').value() ?? [];
return files.find((file) => file.type === 'illustration' && !file.isDeleted);
}

get attachments() {
return this.files.filter((file) => file.type === 'attachment' && !file.isDeleted);
const files = this.hasMany('files').value() ?? [];
return files.filter((file) => file.type === 'attachment' && !file.isDeleted);
}

get isPrototype() {
Expand Down Expand Up @@ -217,7 +219,8 @@ export default class ChallengeModel extends Model {
}

get otherLocalizedChallenges() {
return this.localizedChallenges.filter((localizedChallenge) => localizedChallenge.locale !== this.primaryLocale);
const localizedChallenges = this.hasMany('localizedChallenges').value() ?? [];
return localizedChallenges.filter((localizedChallenge) => localizedChallenge.locale !== this.primaryLocale);
}

set attachmentBaseName(value) {
Expand Down
37 changes: 26 additions & 11 deletions pix-editor/app/models/competence.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,43 @@ export default class CompetenceModel extends Model {
@attr pixId;
@attr source;

@belongsTo('area') area;
@belongsTo('area', { async: true, inverse: 'competences' }) area;

@hasMany('tube') rawTubes;
@hasMany('theme') rawThemes;
@hasMany('tube', { async: true, inverse: 'competence' }) rawTubes;
@hasMany('theme', { async: true, inverse: 'competence' }) rawThemes;

get name() {
return `${this.code} ${this.title}`;
}

get tubes() {
return this.rawTubes.filter((tube) => tube.name !== '@workbench');
const rawTubes = this.hasMany('rawTubes').value();

if (rawTubes === null) return [];

return rawTubes.filter((tube) => tube.name !== '@workbench');
}

get themes() {
return this.rawThemes.filter((theme) => theme.name.indexOf('workbench') === -1);
const rawThemes = this.hasMany('rawThemes').value();

if (rawThemes === null) return [];

return rawThemes.filter((theme) => theme.name.indexOf('workbench') === -1);
}

get sortedThemes() {
return this.themes.sortBy('name').sortBy('index');
}

get productionTubes() {
const allTubes = this.rawTubes.filter((tube) => tube.hasProductionSkills);
return allTubes.sortBy('index');
const rawTubes = this.hasMany('rawTubes').value();

if (rawTubes === null) return [];

return rawTubes
.filter((tube) => tube.hasProductionSkills)
.sortBy('index');
}

get sortedTubes() {
Expand All @@ -59,21 +72,23 @@ export default class CompetenceModel extends Model {
}

get skillCount() {
return this.tubes.map((tube) => tube.skillCount).reduce((count, value)=> {
return this.tubes.map((tube) => tube.skillCount).reduce((count, value) => {
return count + value;
}, 0);
}

get productionSkillCount() {
return this.tubes.map((tube) => tube.productionSkillCount).reduce((count, value)=> {
return this.tubes.map((tube) => tube.productionSkillCount).reduce((count, value) => {
return count + value;
}, 0);
}

get workbenchSkill() {
const workbenchTube = this.rawTubes.find((tube) => tube.name === '@workbench');
const rawTubes = this.hasMany('rawTubes').value() ?? [];
const workbenchTube = rawTubes.find((tube) => tube.name === '@workbench');
if (workbenchTube) {
return workbenchTube.rawSkills.firstObject;
const rawSkills = workbenchTube.hasMany('rawSkills').value() ?? [];
return rawSkills[0] ;
}
return null;
}
Expand Down
10 changes: 7 additions & 3 deletions pix-editor/app/models/framework.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ class FrameworkModel extends Model {

static pix1DFrameworkName = 'Pix 1D';
@attr name;
@hasMany('area') areas;
@hasMany('area', { async: true, inverse: 'framework' }) areas;

get sortedAreas() {
return this.areas
.toArray()
const areas = this.hasMany('areas').value();

if (areas === null) return [];

return areas
.slice()
.sort((areaA, areaB) => parseInt(areaA.code) - parseInt(areaB.code));
}
}
Expand Down
4 changes: 2 additions & 2 deletions pix-editor/app/models/localized-challenge.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export default class LocalizedChallengeModel extends Model {
@attr status;
@attr translations;

@belongsTo('challenge', { inverse: 'localizedChallenges' }) challenge;
@hasMany('attachment', { inverse: 'localizedChallenge' }) files;
@belongsTo('challenge', { inverse: 'localizedChallenges', async: true }) challenge;
@hasMany('attachment', { inverse: 'localizedChallenge', async: true }) files;

get isPrimaryChallenge() {
return this.challenge.get('id') === this.id;
Expand Down
51 changes: 32 additions & 19 deletions pix-editor/app/models/skill.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@ export default class SkillModel extends Model {
@attr i18n;
@attr('number') version;

@belongsTo('tube')
tube;
@belongsTo('tube', { async: true, inverse: 'skills' }) tube;

@hasMany('challenge', { readOnly: true })
challenges;
@hasMany('challenge', { readOnly: true, async: true, inverse: 'skill' }) challenges;

@hasMany('tutorial')
tutoSolution;
@hasMany('tutorial', { async: true, inverse: null }) tutoSolution;

@hasMany('tutorial')
tutoMore;
@hasMany('tutorial', { async: true, inverse: null }) tutoMore;

@service('store') myStore;

Expand Down Expand Up @@ -76,7 +72,11 @@ export default class SkillModel extends Model {
}

get prototypes() {
return this.challenges.filter((challenge) => challenge.isPrototype);
const challenges = this.hasMany('challenges').value();

if (challenges === null) return [];

return challenges.filter((challenge) => challenge.isPrototype);
}

get sortedPrototypes() {
Expand All @@ -92,15 +92,27 @@ export default class SkillModel extends Model {
}

get alternatives() {
return this.challenges.filter((challenge) => !challenge.isPrototype);
const challenges = this.hasMany('challenges').value();

if (challenges === null) return [];

return challenges.filter((challenge) => !challenge.isPrototype);
}

get validatedChallenges() {
return this.challenges.filter((challenge) => challenge.isValidated);
const challenges = this.hasMany('challenges').value();

if (challenges === null) return [];

return challenges.filter((challenge) => challenge.isValidated);
}

get liveChallenges() {
return this.challenges.filter((challenge) => challenge.isLive);
const challenges = this.hasMany('challenges').value();

if (challenges === null) return [];

return challenges.filter((challenge) => challenge.isLive);
}

get isActive() {
Expand Down Expand Up @@ -193,12 +205,14 @@ export default class SkillModel extends Model {
async clone({ tubeDestination, level }) {
const newSkill = this.myStore.createRecord(this.constructor.modelName, {});

return newSkill.save({ adapterOptions: {
clone: true,
skillIdToClone: this.pixId,
tubeDestinationId: tubeDestination.pixId,
level,
} });
return newSkill.save({
adapterOptions: {
clone: true,
skillIdToClone: this.pixId,
tubeDestinationId: tubeDestination.pixId,
level,
},
});
}

_getJSON(fieldsToRemove) {
Expand Down Expand Up @@ -259,4 +273,3 @@ export default class SkillModel extends Model {
}

}

2 changes: 1 addition & 1 deletion pix-editor/app/models/static-course-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default class StaticCourseSummaryModel extends Model {
@attr challengeCount;
@attr isActive;
@attr createdAt;
@hasMany('static-course-tag') tags;
@hasMany('static-course-tag', { async: true, inverse: 'static-course-summary' }) tags;

get previewURL() {
return `https://app.pix.fr/courses/${this.id}`;
Expand Down
4 changes: 2 additions & 2 deletions pix-editor/app/models/static-course.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export default class StaticCourseModel extends Model {
@attr createdAt;
@attr updatedAt;

@hasMany('challenge-summary') challengeSummaries;
@hasMany('static-course-tag') tags;
@hasMany('challenge-summary', { async: true, inverse: 'static-course' }) challengeSummaries;
@hasMany('static-course-tag', { async: true, inverse: 'static-course' }) tags;

get previewURL() {
return `https://app.pix.fr/courses/${this.id}`;
Expand Down
4 changes: 2 additions & 2 deletions pix-editor/app/models/tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export default class TagModel extends Model {
@attr notes;
@attr pixId;

@hasMany('skill') skills;
@hasMany('tutorial') tutorials;
@hasMany('skill', { async: true, inverse: 'tag' }) skills;
@hasMany('tutorial', { async: true, inverse: 'tag' }) tutorials;
}
10 changes: 7 additions & 3 deletions pix-editor/app/models/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ export default class ThemeModel extends Model {
@attr nameEnUs;
@attr index;

@belongsTo('competence') competence;
@hasMany('tube') rawTubes;
@belongsTo('competence', { async: true, inverse: 'themes' }) competence;
@hasMany('tube', { async: true, inverse: 'theme' }) rawTubes;

get tubes() {
return this.rawTubes.filter((tube) => tube.name !== '@workbench').sortBy('index');
const rawTubes = this.hasMany('rawTubes').value();

if (rawTubes === null) return [];

return rawTubes.filter((tube) => tube.name !== '@workbench').sortBy('index');
}

get productionTubes() {
Expand Down
Loading

0 comments on commit 0ba93e4

Please sign in to comment.