Skip to content

Commit

Permalink
Merge pull request #8213 from stopfstedt/replace-has-error-for-resource
Browse files Browse the repository at this point in the history
replaces has-error-in Resource
  • Loading branch information
dartajax authored Nov 7, 2024
2 parents ac7f049 + db8a719 commit 645d054
Show file tree
Hide file tree
Showing 35 changed files with 1,293 additions and 501 deletions.
14 changes: 7 additions & 7 deletions packages/frontend/app/components/bulk-new-users.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -120,28 +120,28 @@
aria-label={{t "general.select"}}
/>
</td>
<td class={{if (has-error-for obj "firstName") "error"}}>
<td class={{if obj.hasErrorForFirstName "error"}}>
{{obj.firstName}}
</td>
<td class={{if (has-error-for obj "lastName") "error"}}>
<td class={{if obj.hasErrorForLastName "error"}}>
{{obj.lastName}}
</td>
<td class={{if (has-error-for obj "middleName") "error"}}>
<td class={{if obj.hasErrorForMiddleName "error"}}>
{{obj.middleName}}
</td>
<td>
{{obj.phone}}
</td>
<td class={{if (has-error-for obj "email") "error"}}>
<td class={{if obj.hasErrorForEmail "error"}}>
{{obj.email}}
</td>
<td class={{if (has-error-for obj "campusId") "error"}}>
<td class={{if obj.hasErrorForCampusId "error"}}>
{{obj.campusId}}
</td>
<td class={{if (has-error-for obj "otherId") "error"}}>
<td class={{if obj.hasErrorForOtherId "error"}}>
{{obj.otherId}}
</td>
<td class={{if (has-error-for obj "username") "error"}}>
<td class={{if obj.hasErrorForUsername "error"}}>
{{obj.username}}
</td>
<td>
Expand Down
63 changes: 63 additions & 0 deletions packages/frontend/app/components/bulk-new-users.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,69 @@ class ProposedUser extends CoreObject {
this.addErrorDisplayForAllFields();
}

@cached
get hasErrorForFirstNameData() {
return new TrackedAsyncData(this.hasErrorFor('firstName'));
}

get hasErrorForFirstName() {
return this.hasErrorForFirstNameData.isResolved ? this.hasErrorForFirstNameData.value : false;
}

@cached
get hasErrorForLastNameData() {
return new TrackedAsyncData(this.hasErrorFor('lastName'));
}

get hasErrorForLastName() {
return this.hasErrorForLastNameData.isResolved ? this.hasErrorForLastNameData.value : false;
}

@cached
get hasErrorForMiddleNameData() {
return new TrackedAsyncData(this.hasErrorFor('middleName'));
}

get hasErrorForMiddleName() {
return this.hasErrorForMiddleNameData.isResolved ? this.hasErrorForMiddleNameData.value : false;
}

@cached
get hasErrorForEmailData() {
return new TrackedAsyncData(this.hasErrorFor('email'));
}

get hasErrorForEmail() {
return this.hasErrorForEmailData.isResolved ? this.hasErrorForEmailData.value : false;
}

@cached
get hasErrorForCampusIdData() {
return new TrackedAsyncData(this.hasErrorFor('campusId'));
}

get hasErrorForCampusId() {
return this.hasErrorForCampusIdData.isResolved ? this.hasErrorForCampusIdData.value : false;
}

@cached
get hasErrorForOtherIdData() {
return new TrackedAsyncData(this.hasErrorFor('otherId'));
}

get hasErrorForOtherId() {
return this.hasErrorForOtherIdData.isResolved ? this.hasErrorForOtherIdData.value : false;
}

@cached
get hasErrorForUsernameData() {
return new TrackedAsyncData(this.hasErrorFor('username'));
}

get hasErrorForUsername() {
return this.hasErrorForUsernameData.isResolved ? this.hasErrorForUsernameData.value : false;
}

async validateUsernameCallback() {
return !this.existingUsernames.includes(this.username);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<EditableField
@value={{this.title}}
@renderHtml={{true}}
@isSaveDisabled={{has-error-for this "title"}}
@isSaveDisabled={{this.hasErrorForTitle}}
@save={{perform this.saveTitleChanges}}
@close={{this.revertTitleChanges}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ export default class ProgramYearObjectiveListItemComponent extends Component {
this.title = this.args.programYearObjective.title;
}

@cached
get hasErrorForTitleData() {
return new TrackedAsyncData(this.hasErrorFor('title'));
}

get hasErrorForTitle() {
return this.hasErrorForTitleData.isResolved ? this.hasErrorForTitleData.value : false;
}

@cached
get upstreamRelationshipsData() {
return new TrackedAsyncData(this.resolveUpstreamRelationships(this.args.programYearObjective));
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/app/components/user-profile-bio.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@
{{on "keyup" this.keyboard}}
data-test-password-input
/>
{{#if (has-error-for this.password)}}
{{#if this.hasErrorForPassword}}
<ValidationError @validatable={{this}} @property="password" />
{{else if (gt this.password.length 0)}}
<span
Expand Down
9 changes: 9 additions & 0 deletions packages/frontend/app/components/user-profile-bio.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ export default class UserProfileBioComponent extends Component {

userSearchTypeConfig = new TrackedAsyncData(this.iliosConfig.getUserSearchType());

@cached
get hasErrorForPasswordData() {
return new TrackedAsyncData(this.hasErrorFor('password'));
}

get hasErrorForPassword() {
return this.hasErrorForPasswordData.isResolved ? this.hasErrorForPasswordData.value : false;
}

@cached
get userSearchType() {
return this.userSearchTypeConfig.isResolved ? this.userSearchTypeConfig.value : null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'frontend/tests/helpers';
import { render } from '@ember/test-helpers';
import { render, settled } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { component } from 'frontend/tests/pages/components/program-year/objective-list-item';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
Expand Down Expand Up @@ -148,4 +148,25 @@ module('Integration | Component | program-year/objective-list-item', function (h
await component.activate();
assert.ok(component.isActive);
});

test('validate description', async function (assert) {
this.set('programYearObjective', this.model);
await render(
hbs`<ProgramYear::ObjectiveListItem
@programYearObjective={{this.programYearObjective}}
@editable={{true}}
/>`,
);
await component.description.openEditor();
assert.notOk(component.description.hasError);
assert.notOk(component.description.savingIsDisabled);
await component.description.edit('a'.repeat(65000));
await settled();
assert.ok(component.description.hasValidationError);
assert.ok(component.description.savingIsDisabled);
await component.description.edit('lorem ipsum');
await settled();
assert.notOk(component.description.hasValidationError);
assert.notOk(component.description.savingIsDisabled);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,25 @@ module('Integration | Component | user profile bio', function (hooks) {
assert.strictEqual(component.password.value, '');
});

test('password validation', async function (assert) {
setupApplicationConfig('form', this);
const userModel = await this.owner.lookup('service:store').findRecord('user', this.user.id);
this.set('user', userModel);

await render(
hbs`<UserProfileBio @isManaging={{true}} @user={{this.user}} @setIsManaging={{(noop)}} />`,
);

await component.password.edit();
assert.notOk(component.password.hasError);
await component.password.set('');
await component.save();
assert.ok(component.password.hasError);
await component.password.set('abcdef');
await component.save();
assert.notOk(component.password.hasError);
});

test('password strength 0 display', async function (assert) {
setupApplicationConfig('form', this);
const userModel = await this.owner.lookup('service:store').findRecord('user', this.user.id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clickable, create, hasClass, isVisible, text } from 'ember-cli-page-object';
import { clickable, create, hasClass, isVisible, property, text } from 'ember-cli-page-object';
import { pageObjectFillInFroalaEditor, pageObjectFroalaEditorValue } from 'ilios-common';
import meshManager from './manage-objective-descriptors';
import competencyManager from './manage-objective-competency';
Expand All @@ -17,6 +17,7 @@ const definition = {
editorContents: pageObjectFroalaEditorValue('[data-test-html-editor]'),
edit: pageObjectFillInFroalaEditor('[data-test-html-editor]'),
save: clickable('.done'),
savingIsDisabled: property('disabled', '.done'),
validationError: text('.validation-error-message'),
hasValidationError: isVisible('.validation-error-message'),
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clickable, create, hasClass, isVisible, text } from 'ember-cli-page-object';
import { clickable, create, hasClass, isVisible, property, text } from 'ember-cli-page-object';
import { pageObjectFillInFroalaEditor, pageObjectFroalaEditorValue } from 'ilios-common';
import meshManager from './manage-objective-descriptors';
import parentManager from './manage-objective-parents';
Expand All @@ -16,6 +16,7 @@ const definition = {
editorContents: pageObjectFroalaEditorValue('[data-test-html-editor]'),
edit: pageObjectFillInFroalaEditor('[data-test-html-editor]'),
save: clickable('.done'),
savingIsDisabled: property('disabled', '.done'),
validationError: text('.validation-error-message'),
hasValidationError: isVisible('.validation-error-message'),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
collection,
create,
fillable,
hasClass,
isPresent,
text,
triggerable,
Expand All @@ -14,6 +15,7 @@ const definition = {
scope: '[data-test-title]',
set: fillable(),
submit: triggerable('keyup', '', { eventProperties: { key: 'Enter' } }),
hasError: hasClass('has-error'),
},
sessionTypes: collection('[data-test-session-type]', {
title: text(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { attribute, clickable, create, fillable, isVisible, text } from 'ember-cli-page-object';
import {
attribute,
clickable,
create,
fillable,
isVisible,
property,
text,
} from 'ember-cli-page-object';
import { pageObjectFillInFroalaEditor } from 'ilios-common';
import postrequisiteEditor from './session/postrequisite-editor';
import yesNoToggle from './toggle-yesno';
import ilmDueDateAndTime from './session-overview-ilm-duedate';
import publicationStatus from './publication-status';
import publicationMenu from './session/publication-menu';

export default create({
const definition = {
scope: '[data-test-session-overview]',
title: {
scope: '[data-test-title]',
Expand Down Expand Up @@ -36,6 +44,7 @@ export default create({
edit: clickable('[data-test-edit]'),
set: pageObjectFillInFroalaEditor('[data-test-html-editor]'),
save: clickable('.done'),
savingIsDisabled: property('disabled', '.done'),
cancel: clickable('.cancel'),
hasError: isVisible('.validation-error-message'),
},
Expand All @@ -45,6 +54,7 @@ export default create({
edit: clickable('[data-test-edit]'),
set: pageObjectFillInFroalaEditor('[data-test-html-editor]'),
save: clickable('.done'),
savingIsDisabled: property('disabled', '.done'),
cancel: clickable('.cancel'),
hasError: isVisible('.validation-error-message'),
},
Expand Down Expand Up @@ -94,4 +104,7 @@ export default create({
},
publicationStatus,
publicationMenu,
});
};

export default definition;
export const component = create(definition);
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { clickable, create, hasClass, isVisible, text } from 'ember-cli-page-object';
import { clickable, create, hasClass, isVisible, property, text } from 'ember-cli-page-object';
import { pageObjectFillInFroalaEditor, pageObjectFroalaEditorValue } from 'ilios-common';
import meshManager from './manage-objective-descriptors';
import parentManager from './manage-objective-parents';
Expand All @@ -16,6 +16,7 @@ const definition = {
editorContents: pageObjectFroalaEditorValue('[data-test-html-editor]'),
edit: pageObjectFillInFroalaEditor('[data-test-html-editor]'),
save: clickable('.done'),
savingIsDisabled: property('disabled', '.done'),
validationError: text('.validation-error-message'),
hasValidationError: isVisible('.validation-error-message'),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<EditableField
@value={{@courseObjective.title}}
@renderHtml={{true}}
@isSaveDisabled={{has-error-for this "title"}}
@isSaveDisabled={{this.hasErrorForTitle}}
@save={{perform this.saveTitleChanges}}
@close={{this.revertTitleChanges}}
>
Expand Down Expand Up @@ -124,4 +124,4 @@
@cancel={{this.cancel}}
/>
{{/if}}
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ export default class CourseObjectiveListItemComponent extends Component {
@tracked termsBuffer = [];
@tracked selectedVocabulary;

@cached
get hasErrorForTitleData() {
return new TrackedAsyncData(this.hasErrorFor('title'));
}

get hasErrorForTitle() {
return this.hasErrorForTitleData.isResolved ? this.hasErrorForTitleData.value : false;
}

@cached
get parentsData() {
return new TrackedAsyncData(this.args.courseObjective.programYearObjectives);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
data-test-copyright-agreement
>
{{t "general.copyrightAgreement"}}
{{#if (has-error-for this "copyrightPermission")}}
{{#if this.hasErrorForCopyrightPermission}}
<br>
<span class="validation-error-message" data-test-agreement-validation-error-message>
{{t "errors.agreementRequired"}}
Expand Down
11 changes: 11 additions & 0 deletions packages/ilios-common/addon/components/new-learningmaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ export default class NewLearningmaterialComponent extends Component {

userModel = new TrackedAsyncData(this.currentUser.getModel());

@cached
get hasErrorForCopyrightPermissionData() {
return new TrackedAsyncData(this.hasErrorFor('copyrightPermission'));
}

get hasErrorForCopyrightPermission() {
return this.hasErrorForCopyrightPermissionData.isResolved
? this.hasErrorForCopyrightPermissionData.value
: false;
}

@cached
get currentUserModel() {
return this.userModel.isResolved ? this.userModel.value : null;
Expand Down
2 changes: 1 addition & 1 deletion packages/ilios-common/addon/components/new-session.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{{on "input" this.changeTitle}}
{{on "keyup" (fn this.addErrorDisplayFor "title")}}
{{on "keyup" this.keyboard}}
class={{if (has-error-for this "title") "has-error"}}
class={{if this.hasErrorForTitle "has-error"}}
disabled={{this.saveNewSession.isRunning}}
data-test-title
>
Expand Down
Loading

0 comments on commit 645d054

Please sign in to comment.