Skip to content

Commit

Permalink
updates for transitions, db edits and refreshes in groups pages
Browse files Browse the repository at this point in the history
frontend/app/

Use injected .router for .transitionTo() instead of this in routes and this.target in controller, in :
  controllers/ group/edit.js : deleteGroup() and groups.js : selectedServerChanged()
  routes/group.js : beforeModel().

adapters/application.js : updateRecord() : use attributesToSave instead of snapshot._internalModel._relationshipProxyCache / changedAttributes.

components/panel/manage-dataset.js :
add : ownedByMe: alias(dataset.owner).
datasetChangeGroup() : objectAttributeChanged(this.dataset, groupId), which pushes the change to dataset record Symbol attributesToSave.

controllers/
group/edit.js and group.js : get services () is replaced by setting controller owner via setupController(), to enable setup of these values via @service.
group.js : alias(model) group.
group/edit.js : removeGroupMemberClient() and removeAllGroupMembers() : pass clientGroup object to removeGroupMember() instead of .id
groups.js : serverObj() : fall back to primaryServer when server name is not given in queryParams.
groups/add.js : addGroup() : pass client object instead of id as clientId.
add group/index.js, with removeGroupMember() copied from controllers/groups.js with one change : get server from .model.server and derive apiServers from that, instead of using server = apiServers.lookupServerName(store.name).

models/
client-group.js : clientId, groupId, client.js : clientGroups and group.js : clientGroups : specify the belongsTo / hasMany relation inverse field name, instead of null.

routes/
group.js : add model().  beforeModel() : record .server instead of .store.
group/edit.js and groups.js : setupController = setupControllerModelOwnerTarget

serializers/
application.js : normalizeResponse() : add store.name to trace.
groups-in.js : normalizeGroupsIn() and groups-in.js : normalizeGroupsOwn() : add param store, used instead of this.store.
groups-own.js : normalize() : add debugger statement - seems not used.

services/controls.js : apiServerSelectedOrPrimary() : access apiServers.lookupServerName without .get().
group/index.hbs : group-members param group change .group -> .model; pass action param removeGroupMember.
utils/data/group.js : getGroups() : groupsPR : pass store to serializer .normalizeGroups{Own,In}()
utils/ember-devel.js : add objectAttributeChanged(), setupControllerModelOwnerTarget().

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Mar 22 15:26:14 2024 +1100
#
# On branch feature/upgradeFrontend
# Your branch is ahead of 'origin/feature/upgradeFrontend' by 1 commit.
#   (use "git push" to publish your local commits)
#
# Changes to be committed:
#	modified:   frontend/app/adapters/application.js
#	modified:   frontend/app/components/panel/manage-dataset.js
#	modified:   frontend/app/controllers/group.js
#	modified:   frontend/app/controllers/group/edit.js
#	new file:   frontend/app/controllers/group/index.js
#	modified:   frontend/app/controllers/groups.js
#	modified:   frontend/app/controllers/groups/add.js
#	modified:   frontend/app/models/client-group.js
#	modified:   frontend/app/models/client.js
#	modified:   frontend/app/models/group.js
#	modified:   frontend/app/routes/group.js
#	modified:   frontend/app/routes/group/edit.js
#	modified:   frontend/app/routes/groups.js
#	modified:   frontend/app/serializers/application.js
#	modified:   frontend/app/serializers/groups-in.js
#	modified:   frontend/app/serializers/groups-own.js
#	modified:   frontend/app/services/controls.js
#	deleted:    frontend/app/services/store.js
#	modified:   frontend/app/templates/group/index.hbs
#	modified:   frontend/app/utils/data/group.js
#	modified:   frontend/app/utils/ember-devel.js
#
# Changes not staged for commit:
#	modified:   frontend/app/controllers/group/index.js
#
# Untracked files:
#	lb4app/client
#	lb4app/dnaSequence.0.fasta
#	lb4app/dnaSequence.1.fasta
#	lb4app/lb3app/common/index/
#	lb4app/tmp/
#	package-lock.json
#
  • Loading branch information
Don-Isdale committed Mar 22, 2024
1 parent 4edfb9b commit d802eb1
Show file tree
Hide file tree
Showing 21 changed files with 239 additions and 74 deletions.
47 changes: 28 additions & 19 deletions frontend/app/adapters/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ var config = {
let data = {};
let
object = store.peekRecord(snapshot.modelName, snapshot.id),
/* changedAttributes now contains relationships in some cases. */
changedAttributes = snapshot.changedAttributes(),
changedAttributesKeys = Object.keys(changedAttributes),
/** object.hasDirtyAttributes seems to be true if either an attribute or relationship has changed.
Expand All @@ -181,24 +182,31 @@ var config = {
* .groupId in the PATCH, to avoid writing [] to .blocks
* This could be used more generally as other changes are added.
*/
/** probably github.com/ef4/ember-data-relationship-tracker offers a better solution. */
rc = snapshot._internalModel._relationshipProxyCache,
changedRelationshipKeys = Object.keys(rc);
if (! changedAttributesKeys.length &&
(snapshot.modelName === 'dataset') &&
(changedRelationshipKeys.length === 1) &&
(changedRelationshipKeys[0] === "groupId" )) {
/* expect changedAttributes is {}.
* If needed to set .groupId and attributes in one save, this can be expanded.
*/
if (changedAttributesKeys.length) {
dLog(fnName, changedAttributes);
/** possibly github.com/ef4/ember-data-relationship-tracker offers a better solution, or :
* https://github.com/danielspaniel/ember-data-change-tracker
* https://www.npmjs.com/package/ember-data-relationship-dirty-tracking
* but they have not been updated to Ember v4.
*/
record = snapshot.record,
attributesToSave = record[Symbol.for('attributesToSave')];
if (attributesToSave?.length) {
dLog(fnName, record.id, attributesToSave);
let attributeName;
while ((attributeName = attributesToSave.pop())) {
/** dataset record.get('clientId') is db id string instead of a proxy;
* to handle that case, could instead do :
* const value = record.get(idField),
* valueId = value.then ? value.get('id') : value
* data[attributeName] = valueId || null;
*/
const idField = attributeName.replace(/Id$/, 'Id.id');
/* map undefined to null, for JSON web API.
* When dataset.groupId is set to null, rc.groupId.get('id') returns
* undefined; map this to null, which is valid JSON in PATCH.
*/
data[attributeName] = record.get(idField) || null;
}
/* when dataset.groupId is set to null, rc.groupId.get('id') returns
* undefined; map this to null, which is valid JSON in PATCH.
* (snapshot._internalModel._record.groupId.content is null)
*/
data.groupId = rc.groupId.get('id') || null;
dLog(fnName, data, record.id, changedAttributes, attributesToSave);
} else if ((changedAttributesKeys.length === 1) && (type.modelName !== 'feature')) {
/* excluding 'feature' because having attributes .value and .values seems to
* confuse snapshot.changedAttributes() - when .values.Ontology is set,
Expand All @@ -215,8 +223,9 @@ var config = {
let
modelName = snapshot.modelName,
serializer = store.serializerFor(modelName),
rename = serializer?.attrs[key];
data[rename || key] = snapshot.__attributes[key];
model = store.modelFor(modelName),
rename = serializer?._getMappedKey(key, model); // was serializer?.attrs[key] in Ember v3
data[rename || key] = snapshot.attr(key); // was .__attributes[key];
} else {
let serializer = store.serializerFor(type.modelName);

Expand Down
9 changes: 7 additions & 2 deletions frontend/app/components/panel/manage-dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { later as run_later } from '@ember/runloop';

import $ from 'jquery';

import { toPromiseProxy, toArrayPromiseProxy } from '../../utils/ember-devel';
import { toPromiseProxy, toArrayPromiseProxy, objectAttributeChanged } from '../../utils/ember-devel';
import { getGroups } from '../../utils/data/group';
import { noGroup } from '../../utils/data/groups';

Expand Down Expand Up @@ -36,7 +36,11 @@ export default ManageBase.extend({

onEditable : function() { dLog('onEditable'); return false; },

ownedByMe: alias("dataset.owner"),
/** alias("dataset.owner") does not appear to be updating, so instead using
* datasetOwned which is roughly equivalent, with the advantage that
* it uses sessionUserId whereas models/record.js : owner() uses .server.clientId
*/
ownedByMe: alias("datasetOwned"),
apiHost : alias("dataset.store.name"),

datasetMeta: computed("dataset._meta", function() {
Expand Down Expand Up @@ -182,6 +186,7 @@ export default ManageBase.extend({
if (this.dataset.get('groupId.id') == group.get('id')) {
dLog(fnName, 'no change', this.dataset.get('id'), group.get('id') );
} else {
objectAttributeChanged(this.dataset, 'groupId');
this.dataset.set('groupId', group === noGroup ? null : group);
this.dataset.save()
.catch((err) => this.set('datasetGroupErrMsg', 'Dataset Group change ' + group.id + ' not saved.\n' + err));
Expand Down
3 changes: 2 additions & 1 deletion frontend/app/controllers/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Controller from '@ember/controller';
import { computed, action } from '@ember/object';
import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { getOwner } from '@ember/application';

// -----------------------------------------------------------------------------

Expand All @@ -18,7 +19,6 @@ export default class GroupController extends Controller {
this.editingName = false;
}


@action
changeGroupName(group, newName) {
const
Expand All @@ -42,6 +42,7 @@ export default class GroupController extends Controller {
}

/** model is group */
@alias('model') group;
@alias('model.server') server;

@action
Expand Down
33 changes: 17 additions & 16 deletions frontend/app/controllers/group/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { computed, action } from '@ember/object';
import { alias } from '@ember/object/computed';
import { getOwner } from '@ember/application';

/* global Ember */

Expand All @@ -25,40 +24,39 @@ const allowGroupsWhenPrivate = false;
* @param model group
*/
export default class GroupEditController extends Controller {
// @service auth;

// @service apiServers;
// apiServers: service(),

// @service session;
// session : service(),

// @service controls;
@service auth;
@service apiServers;
@service session;
@service controls;
@service router;

// newClientName : string;
constructor() {
super();
this.newClientName = undefined;
}

/** lookup owner and services when required. */
/** lookup owner and services when required.
@computed() get services () {
let owner = getOwner(this.target);
let owner = getOwner(this.target || this.model || this.group);
let
apiServers = owner.lookup('service:apiServers'),
session = owner.lookup('service:session'),
auth = owner.lookup('service:auth'),
controls = owner.lookup('service:controls'),
router = owner.lookup('service:router'),
services = {
apiServers, session, auth, controls
apiServers, session, auth, controls, router,
};
return services;
}
@alias('services.apiServers') apiServers;
@alias('services.session') session;
@alias('services.auth') auth;
@alias('services.controls') controls;
@alias('services.router') router;
*/

@alias('model') group;
/** .server.store === .groupStore. */
Expand All @@ -78,6 +76,9 @@ export default class GroupEditController extends Controller {

@action
refresh() {
if (! this.target) {
dLog('refresh', this.model);
}
this.send('refreshModel');
}

Expand Down Expand Up @@ -196,7 +197,7 @@ export default class GroupEditController extends Controller {
fnName = 'removeGroupMemberClient',
clientGroup = this.clientToClientGroup(client);
if (clientGroup) {
this.removeGroupMember(clientGroup.id);
this.removeGroupMember(clientGroup);
}
}

Expand Down Expand Up @@ -231,7 +232,7 @@ export default class GroupEditController extends Controller {
group = this.model,
cgs = group.clientGroups,
destroyPs = cgs.map((cg) => {
return this.removeGroupMember(cg.id);
return this.removeGroupMember(cg);
});
dLog(fnName, cgs);
return Promise.all(destroyPs);
Expand Down Expand Up @@ -279,7 +280,7 @@ export default class GroupEditController extends Controller {
routeGroups = owner.lookup('route:groups');
routeGroups.transitionTo('groups');
*/
this.target.transitionTo('groups');
this.router.transitionTo('groups');
})
.catch((error) => {
const errorDetail = error?.errors[0];
Expand Down
51 changes: 51 additions & 0 deletions frontend/app/controllers/group/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Controller from '@ember/controller';
import { getOwner } from '@ember/application';
import { computed, action } from '@ember/object';

import { removeGroupMember } from '../../utils/data/group';

// -----------------------------------------------------------------------------

const dLog = console.debug;

// -----------------------------------------------------------------------------


/**
* @param model group
*/
export default class GroupIndexController extends Controller {

//----------------------------------------------------------------------------

// copied from controllers/groups.js
/**
* @param clientGroup is from this.model.groupsIn, via #each in .hbs
*/
@action
removeGroupMember(clientGroup) {
const
fnName = 'removeGroupMember',
msgName = fnName + 'Msg',
/** model is group */
server = this.model.server,
apiServers = server.apiServers,
clientGroupId = clientGroup.id;

this.set(msgName, '');
let
destroyP = removeGroupMember(apiServers, server, clientGroup, clientGroupId);
destroyP
.then((cg) => {
this.set('selectedClientGroupId', null);
this.send('refreshModel');
})
.catch((errorText) => {
this.set(msgName, errorText);
});
return destroyP;
};

//----------------------------------------------------------------------------

}
21 changes: 15 additions & 6 deletions frontend/app/controllers/groups.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { computed, action } from '@ember/object';
import { alias } from '@ember/object/computed';
import { getOwner } from '@ember/application';
Expand All @@ -12,15 +13,18 @@ const dLog = console.debug;
// -----------------------------------------------------------------------------

export default class GroupsController extends Controller {

// @service apiServers;
@service router;
@service apiServers;

queryParams = ['server'];
// .server is initially undefined.

@computed('server')
get serverObj() {
const server = this.apiServers.lookupServerTabId(this.server);
const
apiServers = this.apiServers,
server = this.server ? apiServers.lookupServerTabId(this.server) :
apiServers.primaryServer;
return server;
}

Expand All @@ -29,28 +33,33 @@ export default class GroupsController extends Controller {
this.newClientName = undefined;
}

/** lookup owner and services when required. */
/** lookup owner and services when required.
@computed() get services () {
let apiServers;
let router;
if (this.target) {
dLog('services', 'target route', this.target);
let owner = getOwner(this.target);
apiServers = owner.lookup('service:apiServers');
router = owner.lookup('service:router');
} else if (this.model.server) {
apiServers = this.model.server.apiServers;
}
const
services = {
apiServers
apiServers, router,
};
return services;
}
@alias('services.apiServers') apiServers;
@alias('services.router') router;
*/

@action
selectedServerChanged(server) {
dLog('selectedServerChanged', server);
let queryParams = {server : server.tabId};
this.target.transitionTo({queryParams});
this.router.transitionTo({queryParams});
// this.send('refreshModel');
}

Expand Down
3 changes: 2 additions & 1 deletion frontend/app/controllers/groups/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ export default Controller.extend({
dLog(fnName, this.clientIdSession);
{
let store = this.get('apiServers.primaryServer.store');
const client = store.peekRecord('client', clientId);
dLog(fnName, this.store, store);

{
var group = store.createRecord('group', {
name: newGroupName,
clientId
clientId : client
});
let p = group.save();

Expand Down
4 changes: 2 additions & 2 deletions frontend/app/models/client-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import Model, { attr, belongsTo } from '@ember-data/model';

export default class ClientGroupModel extends Model {

@belongsTo('client', { async: true, inverse : null/*'clientGroup'*/ }) clientId;
@belongsTo('group', { async: true, inverse : null/*'clientGroups'*/ }) groupId;
@belongsTo('client', { async: true, inverse : 'clientGroups' }) clientId;
@belongsTo('group', { async: true, inverse : 'clientGroups' }) groupId;

@attr('boolean') isVisible;

Expand Down
2 changes: 1 addition & 1 deletion frontend/app/models/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export default class ClientModel extends Model {

@hasMany('group', {async: true, inverse : 'clientId'}) groupsOwn;
@hasMany('group', {async: true, inverse : 'clients'}) groups;
@hasMany('client-group', {async: true, inverse : null/*'client'*/}) clientGroups;
@hasMany('client-group', {async: true, inverse : 'clientId'}) clientGroups;

}
2 changes: 1 addition & 1 deletion frontend/app/models/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default Model.extend({
clientId : belongsTo('client', {async: true, inverse: null/*'groupsOwn'*/}),
/** members of the group */
clients: hasMany('client', {async: false, inverse: null/*'groups'*/}),
clientGroups: hasMany('client-group', { async: false, inverse: null/*'group'*/ }),
clientGroups: hasMany('client-group', { async: false, inverse: 'groupId'}),

// ---------------------------------------------------------------------------

Expand Down
Loading

0 comments on commit d802eb1

Please sign in to comment.