Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 6 additions & 75 deletions addon/controllers/api-keys/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { format as formatDate } from 'date-fns';
import getWithDefault from '@fleetbase/ember-core/utils/get-with-default';

export default class ApiKeysIndexController extends Controller {
@service apiKeyActions;
@service currentUser;
@service intl;
@service modalsManager;
Expand Down Expand Up @@ -261,83 +262,13 @@ export default class ApiKeysIndexController extends Controller {
this.currentUser.setOption('testKey', value);
}

/**
* Toggles modal to create a new API key
*
* @void
*/
@action createApiKey() {
const formPermission = 'developers create api-key';
const apiKey = this.store.createRecord('api-credential', {
test_mode: this.testMode,
});

this.editApiKey(apiKey, {
title: this.intl.t('developers.api-keys.index.new-api-key-title'),
acceptButtonIcon: 'check',
acceptButtonIconPrefix: 'fas',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
successMessage: this.intl.t('developers.api-keys.index.new-api-key-message'),
formPermission,
apiKey,
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await apiKey.save();
this.notifications.success(modal.getOption('successMessage'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
});
// Creating and editing keys lives in the api-key-actions service so other engines can open these dialogs too.
@action createApiKey(...args) {
return this.apiKeyActions.createApiKey(...args);
}

/**
* Toggles modal to create a new API key
*
* @void
*/
@action editApiKey(apiKey, options = {}) {
const formPermission = 'developers update api-key';
this.modalsManager.show('modals/api-key-form', {
title: this.intl.t('developers.api-keys.index.edit-api-key-title'),
acceptButtonIcon: 'save',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
successMessage: this.intl.t('developers.api-keys.index.edit-api-key-message'),
expirationOptions: this.expirationOptions,
testMode: this.currentUser.getOption('sandbox') || false,
apiKey,
formPermission,
setExpiration: ({ target }) => {
apiKey.expires_at = target.value || null;
},
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await apiKey.save();
this.notifications.success(modal.getOption('successMessage'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
...options,
});
@action editApiKey(...args) {
return this.apiKeyActions.editApiKey(...args);
}

/**
Expand Down
152 changes: 8 additions & 144 deletions addon/controllers/webhooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import fromStore from '@fleetbase/ember-core/decorators/legacy-from-store';
import fetchFrom from '@fleetbase/ember-core/decorators/legacy-fetch-from';

export default class WebhooksIndexController extends BaseController {
@service webhookActions;
@service currentUser;
@service intl;
@service modalsManager;
Expand Down Expand Up @@ -177,154 +178,17 @@ export default class WebhooksIndexController extends BaseController {
this.query = value;
}

/**
* Toggles modal to create a new API key
*
* @void
*/
@action createWebhook() {
const formPermission = 'developers create webhook';
const webhook = this.store.createRecord('webhook-endpoint', {
events: [],
mode: this.currentUser.getOption('sandbox') ? 'test' : 'live',
});

this.editWebhook(webhook, {
title: this.intl.t('developers.webhooks.index.add-webhook'),
acceptButtonText: this.intl.t('developers.webhooks.index.add-webhook-button-text'),
acceptButtonIcon: 'check',
acceptButtonIconPrefix: 'fas',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
formPermission,
webhook,
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await webhook.save();
this.notifications.success(this.intl.t('developers.webhooks.index.new-webhook-success-message'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
});
// Webhook dialogs live in the webhook-actions service so other engines can open them too.
@action createWebhook(...args) {
return this.webhookActions.createWebhook(...args);
}

/**
* Triggers dialog to edit webhook
*
* @param {WebhookEndpointModel} webhook
* @param {Object} options
* @void
*/
@action async editWebhook(webhook, options = {}) {
await this.apiCredentials;

const formPermission = 'developers update webhook';
this.modalsManager.show('modals/webhook-form', {
title: this.intl.t('developers.webhooks.index.edit-webhook-endpoint'),
acceptButtonText: this.intl.t('developers.webhooks.index.edit-webhook-endpoint-button-text'),
acceptButtonIcon: 'save',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
formPermission,
declineButtonIcon: 'times',
declineButtonIconPrefix: 'fas',
eventOptions: this.groupedApiEvents,
versionOptions: this.apiVersions,
apiCredentialOptions: this.apiCredentials,
webhook,
setVersion: ({ target }) => {
webhook.version = target.value || null;
},
setApiCredential: ({ target }) => {
webhook.api_credential_uuid = target.value || null;
},
searchEvents: (query) => {
if (typeof query !== 'string') {
return;
}
const resources = Object.keys(this.groupedApiEvents);
const filteredEvents = {};
resources.forEach((eventResource) => {
filteredEvents[eventResource] = this.groupedApiEvents[eventResource].filter((event) => {
return event.toLowerCase().includes(query.toLowerCase());
});
// if 0 events remove from filter
if (filteredEvents[eventResource].length === 0) {
delete filteredEvents[eventResource];
}
});
this.modalsManager.setOption('eventOptions', filteredEvents);
},
addEvent: (event) => {
if (webhook.events.includes(event)) {
return;
}

webhook.events.pushObject(event);
},
removeEvent: (event) => {
webhook.events.removeObject(event);
},
clearEvents: () => {
webhook.events.clear();
},
receiveAllEvents: () => {
webhook.events.pushObjects(this.webhookEvents);
},
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await webhook.save();
this.notifications.success(this.intl.t('developers.webhooks.index.new-webhook-success-message'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
...options,
});
@action editWebhook(...args) {
return this.webhookActions.editWebhook(...args);
}

/**
* Toggles dialog to delete webhook
*
* @param {WebhookEndpointModel} webhook
* @param {Object} options
* @void
*/
@action deleteWebhook(webhook, options = {}) {
this.modalsManager.confirm({
title: this.intl.t('developers.webhooks.index.delete-webhook-endpoint'),
body: this.intl.t('developers.webhooks.index.delete-webhook-endpoint-body'),
confirm: async (modal) => {
modal.startLoading();

try {
await webhook.destroyRecord();
this.notifications.success(this.intl.t('developers.webhooks.index.delete-webhook-success-message'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
...options,
});
@action deleteWebhook(...args) {
return this.webhookActions.deleteWebhook(...args);
}

/**
Expand Down
102 changes: 102 additions & 0 deletions addon/services/api-key-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import ResourceActionService from '@fleetbase/ember-core/services/resource-action';
import { action } from '@ember/object';

/**
* API key actions shared by the Developers console and other engines (for example Fleetbase AI).
*/
export default class ApiKeyActionsService extends ResourceActionService {
expirationOptions = ['never', 'immediately', 'in 1 hour', 'in 24 hours', 'in 3 days', 'in 7 days'];

constructor() {
super(...arguments);
this.initialize('api-credential', { permissionPrefix: 'developers', mountPrefix: 'console.developers' });
}

transition = {
list: () => this.transitionTo('api-keys.index'),
};

modal = {
create: (...args) => this.createApiKey(...args),
edit: (...args) => this.editApiKey(...args),
};

/**
* Toggles modal to create a new API key
*
* @void
*/
@action createApiKey() {
const formPermission = 'developers create api-key';
const apiKey = this.store.createRecord('api-credential', {
test_mode: this.currentUser.getOption('sandbox') || false,
});

this.editApiKey(apiKey, {
title: this.intl.t('developers.api-keys.index.new-api-key-title'),
acceptButtonIcon: 'check',
acceptButtonIconPrefix: 'fas',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
successMessage: this.intl.t('developers.api-keys.index.new-api-key-message'),
formPermission,
apiKey,
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await apiKey.save();
this.notifications.success(modal.getOption('successMessage'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
});
}

/**
* Opens the dialog to edit an API key
*
* @void
*/
@action editApiKey(apiKey, options = {}) {
const formPermission = 'developers update api-key';
this.modalsManager.show('modals/api-key-form', {
title: this.intl.t('developers.api-keys.index.edit-api-key-title'),
acceptButtonIcon: 'save',
acceptButtonDisabled: this.abilities.cannot(formPermission),
acceptButtonHelpText: this.abilities.cannot(formPermission) ? this.intl.t('common.unauthorized') : null,
successMessage: this.intl.t('developers.api-keys.index.edit-api-key-message'),
expirationOptions: this.expirationOptions,
testMode: this.currentUser.getOption('sandbox') || false,
apiKey,
formPermission,
setExpiration: ({ target }) => {
apiKey.expires_at = target.value || null;
},
confirm: async (modal) => {
modal.startLoading();

if (this.abilities.cannot(formPermission)) {
return this.notifications.warning(this.intl.t('common.permissions-required-for-changes'));
}

try {
await apiKey.save();
this.notifications.success(modal.getOption('successMessage'));
return this.hostRouter.refresh();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
...options,
});
}
}
Loading
Loading