Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Refactor path-help service #28444

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
110 changes: 84 additions & 26 deletions ui/app/adapters/generated-item-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,100 @@
import ApplicationAdapter from './application';
import { task } from 'ember-concurrency';
import { service } from '@ember/service';
import { sanitizePath } from 'core/utils/sanitize-path';
import { encodePath } from 'vault/utils/path-encoding-helpers';
import { tracked } from '@glimmer/tracking';

export default ApplicationAdapter.extend({
store: service(),
namespace: 'v1',
urlForItem() {},
dynamicApiPath: '',
export default class GeneratedItemListAdapter extends ApplicationAdapter {
@service store;
namespace = 'v1';

getDynamicApiPath: task(function* (id) {
// TODO: remove yield at some point.
const result = yield this.store.peekRecord('auth-method', id);
this.dynamicApiPath = result.apiPath;
return;
}),
// these items are set within getNewAdapter in path-help service
@tracked apiPath = '';
paths = {};

fetchByQuery: task(function* (store, query, isList) {
getDynamicApiPath(id) {
const result = this.store.peekRecord('auth-method', id);
this.apiPath = result.apiPath;
return result.apiPath;
}

fetchByQuery = task(async (store, query, isList) => {
const { id } = query;
const data = {};
const payload = {};
if (isList) {
data.list = true;
yield this.getDynamicApiPath.perform(id);
payload.list = true;
}
const path = isList ? this.getDynamicApiPath(id) : '';

return this.ajax(this.urlForItem(id, isList, this.dynamicApiPath), 'GET', { data }).then((resp) => {
const data = {
id,
method: id,
};
return { ...resp, ...data };
});
}),
const resp = await this.ajax(this.urlForItem(id, isList, path), 'GET', { data: payload });
const data = {
id,
method: id,
};
return { ...resp, ...data };
});

query(store, type, query) {
return this.fetchByQuery.perform(store, query, true);
},
}

queryRecord(store, type, query) {
return this.fetchByQuery.perform(store, query);
},
});
}

urlForItem(id, isList, dynamicApiPath) {
const itemType = sanitizePath(this.paths.getPath);
let url;
id = encodePath(id);
// the apiPath changes when you switch between routes but the apiPath variable does not unless the model is reloaded
// overwrite apiPath if dynamicApiPath exist.
// dynamicApiPath comes from the model->adapter
let apiPath = this.apiPath;
if (dynamicApiPath) {
apiPath = dynamicApiPath;
}
// isList indicates whether we are viewing the list page
// of a top-level item such as userpass
if (isList) {
url = `${this.buildURL()}/${apiPath}${itemType}/`;
} else {
// build the URL for the show page of a nested item
// such as a userpass group
url = `${this.buildURL()}/${apiPath}${itemType}/${id}`;
}

return url;
}

urlForQueryRecord(id, modelName) {
return this.urlForItem(id, modelName);
}

urlForUpdateRecord(id) {
const itemType = this.paths.createPath.slice(1, this.paths.createPath.indexOf('{') - 1);
return `${this.buildURL()}/${this.apiPath}${itemType}/${id}`;
}

urlForCreateRecord(modelType, snapshot) {
const id = snapshot.record.mutableId; // computed property that returns either id or private settable _id value
const path = this.paths.createPath.slice(1, this.paths.createPath.indexOf('{') - 1);
return `${this.buildURL()}/${this.apiPath}${path}/${id}`;
}

urlForDeleteRecord(id) {
const path = this.paths.deletePath.slice(1, this.paths.deletePath.indexOf('{') - 1);
return `${this.buildURL()}/${this.apiPath}${path}/${id}`;
}

createRecord(store, type, snapshot) {
return super.createRecord(...arguments).then((response) => {
// if the server does not return an id and one has not been set on the model we need to set it manually from the mutableId value
if (!response?.id && !snapshot.record.id) {
snapshot.record.id = snapshot.record.mutableId;
snapshot.id = snapshot.record.id;
}
return response;
});
}
}
35 changes: 35 additions & 0 deletions ui/app/models/generated-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/

import Model from '@ember-data/model';

// This model is used for OpenApi-generated models in path-help service's getNewModel method
export default class GeneratedItemModel extends Model {
allFields = [];

get fieldGroups() {
const groups = {
default: [],
};
const fieldGroups = [];
this.constructor.eachAttribute((name, attr) => {
// if the attr comes in with a fieldGroup from OpenAPI,
if (attr.options.fieldGroup) {
if (groups[attr.options.fieldGroup]) {
groups[attr.options.fieldGroup].push(attr);
} else {
groups[attr.options.fieldGroup] = [attr];
}
} else {
// otherwise just add that attr to the default group
groups.default.push(attr);
}
});
for (const group in groups) {
fieldGroups.push({ [group]: groups[group] });
}
return fieldGroups;
}
}
Loading
Loading