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: convert mount backend code to TS #27349

Merged
merged 5 commits into from
Jun 4, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import { waitFor } from '@ember/test-waiters';
import { methods } from 'vault/helpers/mountable-auth-methods';
import { isAddonEngine, allEngines } from 'vault/helpers/mountable-secret-engines';

import type FlashMessageService from 'vault/services/flash-messages';
import type Store from '@ember-data/store';

import type { AuthEnableModel } from 'vault/routes/vault/cluster/settings/auth/enable';
import type { MountSecretBackendModel } from 'vault/routes/vault/cluster/settings/mount-secret-backend';

/**
* @module MountBackendForm
* The `MountBackendForm` is used to mount either a secret or auth backend.
Expand All @@ -24,9 +30,17 @@ import { isAddonEngine, allEngines } from 'vault/helpers/mountable-secret-engine
*
*/

export default class MountBackendForm extends Component {
@service store;
@service flashMessages;
type MountModel = MountSecretBackendModel | AuthEnableModel;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this component is only rendered on 2 routes:

Screenshot 2024-06-03 at 6 25 34 PM

in both instances, the component directly receives the result of the model hook as its argument for @mountModel. this is why i set up the types this way.

initially, i thought about setting the type to be either SecretEngineModel or AuthMethodModel. however, this setup provides more flexibility -- it allows for potential changes in the route model that may include properties not specifically part of the underlying Ember data models.


interface Args {
mountModel: MountModel;
mountType: 'secret' | 'auth';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got these options from here:

* @param {string} [mountType=auth] - mount type can be `auth` or `secret`

onMountSuccess: (type: string, path: string, useEngineRoute: boolean) => void;
}

export default class MountBackendForm extends Component<Args> {
@service declare readonly store: Store;
@service declare readonly flashMessages: FlashMessageService;

// validation related properties
@tracked modelValidations = null;
Expand All @@ -40,10 +54,10 @@ export default class MountBackendForm extends Component {
if (noTeardown && this.args?.mountModel?.isNew) {
this.args.mountModel.unloadRecord();
}
super.willDestroy(...arguments);
super.willDestroy();
}

checkPathChange(type) {
checkPathChange(type: string) {
if (!type) return;
const mount = this.args.mountModel;
const currentPath = mount.path;
Expand All @@ -58,8 +72,8 @@ export default class MountBackendForm extends Component {
}
}

typeChangeSideEffect(type) {
if (!this.args.mountType === 'secret') return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS caught this, which seemed like a typo so i fixed it 😮

typeChangeSideEffect(type: string) {
if (this.args.mountType !== 'secret') return;
if (type === 'pki') {
// If type PKI, set max lease to ~10years
this.args.mountModel.config.maxLeaseTtl = '3650d';
Expand All @@ -69,7 +83,7 @@ export default class MountBackendForm extends Component {
}
}

checkModelValidity(model) {
checkModelValidity(model: MountModel) {
const { isValid, state, invalidFormMessage } = model.validate();
this.modelValidations = state;
this.invalidFormAlert = invalidFormMessage;
Expand Down Expand Up @@ -113,7 +127,7 @@ export default class MountBackendForm extends Component {

@task
@waitFor
*mountBackend(event) {
*mountBackend(event: Event) {
event.preventDefault();
const mountModel = this.args.mountModel;
const { type, path } = mountModel;
Expand Down Expand Up @@ -165,13 +179,13 @@ export default class MountBackendForm extends Component {
}

@action
onKeyUp(name, value) {
onKeyUp(name: string, value: string) {
this.args.mountModel[name] = value;
this.checkModelWarnings();
}

@action
setMountType(value) {
setMountType(value: string) {
this.args.mountModel.type = value;
this.typeChangeSideEffect(value);
this.checkPathChange(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import Route from '@ember/routing/route';
import { service } from '@ember/service';

import type { ModelFrom } from 'vault/vault/route';
import type Store from '@ember-data/store';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i noticed we've been importing the Store type 2 different ways. one is this way, and the other is like this:

import type StoreService from 'vault/services/store';

however importing the type from @ember-data works better since it recognizes that properties like isDestroying etc are indeed on that type. the alternative way of importing Store caused a bunch of type errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's strange, because in the store.d.ts file we're extending Store from @ember-data/store 🤔 Should be harmless here since we're not using any of the extended methods here, but smells like something wrong in our ts setup


export type AuthEnableModel = ModelFrom<VaultClusterSettingsAuthEnableRoute>;

export default class VaultClusterSettingsAuthEnableRoute extends Route {
@service store;
@service declare readonly store: Store;

model() {
const authMethod = this.store.createRecord('auth-method');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import Route from '@ember/routing/route';
import { service } from '@ember/service';

import type { ModelFrom } from 'vault/vault/route';
import type Store from '@ember-data/store';

export type MountSecretBackendModel = ModelFrom<VaultClusterSettingsMountSecretBackendRoute>;

export default class VaultClusterSettingsMountSecretBackendRoute extends Route {
@service store;
@service declare readonly store: Store;

model() {
const secretEngine = this.store.createRecord('secret-engine');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import type { ValidationMap } from 'vault/vault/app-types';

/**
* @module FormFieldGroups
Expand All @@ -22,11 +23,20 @@ import { action } from '@ember/object';
* @param {string} [groupName=fieldGroups] - attribute name where the field groups are
*/

export default class FormFieldGroupsComponent extends Component {
@tracked showGroup = null;
interface Args {
model: Record<string, unknown>;
renderGroup?: string;
onChange?: (value: string) => void;
onKeyUp?: (value: string) => void;
modelValidations?: ValidationMap;
groupName?: string;
}

export default class FormFieldGroupsComponent extends Component<Args> {
@tracked showGroup: string | null = null;

@action
toggleGroup(group, isOpen) {
toggleGroup(group: string, isOpen: boolean) {
this.showGroup = isOpen ? group : null;
}

Expand Down
Loading