3.7.3. User Preferences
Steps to implement the feature
In order to implement this feature take the following steps:
Add the object with name UserPreferences to model.xml by copying the content of user-preferences-object.xml. into model.xml.
1<model> 2 <package> 3 <metadata> 4 5 </metadata> 6 7 <object name="UserPreferences"> 8 9 </object> 10 </package> 11</model>
Note
If you are reading this documentation on paper you can find the file in the next section Files.
Add the highlighted code to the package metadata in model.xml:
1<model> 2 <package> 3 <metadata> 4 5 <owner> 6 <keyword>Owner</keyword> 7 <role>USER</role> 8 <url.prefix>owner</url.prefix> 9 </owner> 10 </metadata> 11 </package> 12 ... 13</model>
Add the highlighted line to pattern.xml:
1<pattern> 2 3 <external.file id="libJH/jhipster620_angular800/frontend/webapp/app/account/preferences_route_ts.xml" skip="false" /> 4 5</pattern>
Generate the Runtime Model with the Runtime Model buildset.
Generate all
Have Liquibase create the UserPreferences table upon startup of the application:
1<?xml version="1.1" encoding="UTF-8" standalone="no"?> 2<databaseChangeLog> 3 ... 4 [insert changesets here] 5</databaseChangeLog>In liquibase-alters-changeLog.xml replace referencedTableName=”user” with referencedTableName=”jhi_user” in the highlighted line:
1<addForeignKeyConstraint 2 baseColumnNames="user_id" 3 baseTableName="user_preferences" 4 constraintName="fk_user_preferences_user_id_to_user" 5 deferrable="false" 6 initiallyDeferred="false" 7 onDelete="NO ACTION" 8 onUpdate="NO ACTION" 9 referencedColumnNames="id" 10 referencedTableName="user" 11/>
Adjust the custom file generated for the user preferences Angular component:
[project]-metafactory\src\snippets\[frontend]\owner\edit\edit-component-userpreferences.ftl
Add the parameter this.id to the getMyUserPreferencesEditDto call:
1<#assign onInitCode> 2ngOnInit() { 3 // EDIT: retrieve the instance of this UserPreferences 4 this.subs.sink = this.ownerUserPreferencesService.getMyUserPreferencesEditDto(this.id).subscribe((data: OwnerUserPreferencesEditDto) => { 5 this.ownerUserPreferencesEditDto = data; 6 this.buildFormGroup(); 7 }); 8} 9</#assign>
Add the project specific user preferences to model.xml:
User preferences can be added to attributes and references.
Attributes
For each attribute of an object that you would like to be initially set to a user preference, perform the following steps:
Add <user.preferences /> to the existing attribute.
Add a new attribute to the UserPreferences object with the name [object.name?uncap_first][attribute.name?cap_first], e.g. hourAmount.
Add metadata to the new attribute in the UserPreferences object:
1<object name="UserPreferences">
<<<<<<< HEAD
- <metadata>
- <edit.owner.row2>
<col1>label</col1> <col1.colspan>3</col1.colspan> <col2>widget</col2> <col2>
<colspan>3</colspan>
</col2>
</edit.owner.row2>
</metadata>
</attribute>
</object>
Add code to [project]-metafactory\src\snippets\[frontend]\owner\edit\edit-template-userpreferences.ftl to generate the rendering of the newly added user preference.
<@generalMaterial.renderField false ''> <@generalMaterial.renderFieldLabel userPreferences.[attribute.name] metadataKey tsUserPreferences /> <@generalMaterial.renderFieldBody wrapDivField=true wrapSecondDivField=true> <@am.renderFormGroup userPreferences.[attribute.name]> <@am.renderEdit userPreferences.[attribute.name] metadataKey tsUserPreferences /> </@am.renderFormGroup> </@generalMaterial.renderFieldBody> </@generalMaterial.renderField>Replace [attribute.name] with the attribute name as defined in the UserPreferences object, e.g. hourAmount.
Add a changeSet for the creation of the newly added project specific user preferences attribute at the end of liquibase-alters-changeLog.xml.
References
For each reference of an object that you would like to be initially set to a user preference, perform the following steps:
Add <user.preferences /> to the reference that you would like to be initially set to a user preference.
Add a reference to the UserPreferences object with the name [object.name?uncap_first][reference.name?cap_first], e.g. hourTask.
Add metadata to this reference:
1<object name="UserPreferences">
<<<<<<< HEAD
- <metadata>
- <edit.owner.row2>
<col1>label</col1> <col1.colspan>3</col1.colspan> <col2>widget</col2> <col2>
<colspan>3</colspan>
</col2>
</edit.owner.row2>
</metadata>
</reference>
</object>
Add code to [project]-metafactory\src\snippets\[frontend]\owner\edit\edit-template-userpreferences.ftl to generate the rendering of the newly added user preference.
- <<<<<<< HEAD
- caption:
edit-template-userpreferences.ftl for rendering a reference
- name:
edit-template-userpreferences.ftl3
- <ng-container *ngIf=”parentContext===undefined || parentContext.parentReference!=’[reference.name]’”>
- <@generalMaterial.renderField>
<@generalMaterial.renderFieldLabel userPreferences.[reference.name] metadataKey tsUserPreferences /> <@generalMaterial.renderFieldBody wrapDivField=true>
- <@am.renderFormGroup userPreferences.[reference.name]>
<@am.renderEdit userPreferences.[reference.name] metadataKey tsUserPreferences />
</ng-container>
Replace [reference.name] with the reference name as defined in the UserPreferences object, e.g. hourTask.
Add a changeSet for the creation of the newly added project specific user preferences reference at the end of liquibase-alters-changeLog.xml.
Generate the Runtime Model with the Runtime Model buildset.
Generate all
Translate User Preferences
[project]\[frontend]\src\main\webapp\i18n\en\userpreferences.json
[project]\[frontend]\src\main\webapp\i18n\nl\userpreferences.json
Add menu item for User Preferences to the project’s top menu:
Different projects have different top menu’s. So adding a menu item for User Preferences requires manual addition.
Run the application
3.7.3.1. Files
In this section you can find the files you can use in implementing the feature.
<object name="UserPreferences">
<metadata>
<application.angular>true</application.angular>
<class.jpa.type>entity</class.jpa.type>
<createAngularFactories>true</createAngularFactories>
<createAngularRoute>true</createAngularRoute>
<createFixture>true</createFixture>
<createPojo>true</createPojo>
<createRepository>true</createRepository>
<createSearchDto>true</createSearchDto>
<createService>true</createService>
<createTranslationTemplate>true</createTranslationTemplate>
<crud>
<batch.delete>false</batch.delete>
<save.and.create>false</save.and.create>
</crud>
<display>
<field>user</field>
<format>%1$s</format>
</display>
<dto>owner</dto>
<dto.owner>
<keyword>Owner</keyword>
<prefix>my</prefix>
<role>USER</role>
<url.prefix>owner</url.prefix>
</dto.owner>
<edit>owner</edit>
<edit.owner>
<columnCount>6</columnCount>
<createCustomComponent>true</createCustomComponent>
<createCustomLayout>true</createCustomLayout>
<defaultFocus>row1.col2</defaultFocus>
<displayMode>page</displayMode>
<ngmodel>userPreferences</ngmodel>
<propertyprefix>edit.owner</propertyprefix>
<renderSmall>true</renderSmall>
<rowCount>4</rowCount>
<serial.version>1L</serial.version>
</edit.owner>
<enum>false</enum>
<filters.include.null>false</filters.include.null>
<find>
<as.selectable.dto>false</as.selectable.dto>
<by>
<autocomplete>false</autocomplete>
<autocomplete.dto>false</autocomplete.dto>
</by>
</find>
<isCouplingEntity>false</isCouplingEntity>
<jpa.annotation.class>javax.persistence.Entity</jpa.annotation.class>
<list.owner.excel.createExport>false</list.owner.excel.createExport>
<name.plural>UserPreferences</name.plural>
<overview.uses.paging>true</overview.uses.paging>
<search>false</search>
<search.tab>false</search.tab>
<serialVersionUID>0</serialVersionUID>
<show>
<detail.crudButtons>false</detail.crudButtons>
<overview.crudButtons>false</overview.crudButtons>
</show>
</metadata>
<reference name="user" type="User" multiplicity="1..1" notnull="true">
<metadata>
<create.finder.method.single>true</create.finder.method.single>
<crud.create.from.edit>false</crud.create.from.edit>
<dto.owner.edit.render.custom.display.field>false</dto.owner.edit.render.custom.display.field>
<edit.owner>
<render.with.grouping>false</render.with.grouping>
<row1>
<col1>label</col1>
<col1.colspan>3</col1.colspan>
<col2>widget</col2>
<col2.colspan>3</col2.colspan>
</row1>
</edit.owner>
<jpa>
<fetchType>lazy</fetchType>
<mapsid>false</mapsid>
<onetoone.owner>true</onetoone.owner>
<relation>OneToOne</relation>
</jpa>
<search.for.null.value>false</search.for.null.value>
</metadata>
</reference>
</object>
3.7.3.2. Developer notes
Important
For projects that do not have a UserPreferences object in model.xml yet, the aim is to generate no user preferences related code.
For projects like AMI that do have a UserPreferences object in model.xml, the aim is to let AMI’s custom patterns/snippets generate all user preferences related code, so no significant outgoing changes should occur.