Files
vault/ui/lib/core/addon/components/info-table-item-array.js
lane-wetmore 4051cb4d4c UI: Remove custom tag class and replace with Hds::Badge (#29475)
* replace custom tag class with Hds::Badge

* another wave of custom class replacements

* remove tag class styles and cleanup

* add changelog entry

* fix changelog name

* remove changelog entry and old styles and clean up

* remove extra classes and clean up

* one more clean up section

* update tests

* fix value check

* updated test

* update tests

* switch to code elements with specific styling and cleanup
2025-02-07 15:29:12 -06:00

94 lines
4.2 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { assert } from '@ember/debug';
import { action } from '@ember/object';
import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
/**
* @module InfoTableItemArray
* The `InfoTableItemArray` component handles arrays in the info-table-row component.
* If an array has more than 10 items, then only 5 are displayed and a count of total items is displayed next to the five.
* If a isLink is true than a link can be set for the use to click on the specific array item
* If a wildcard is a potential variable in the string of an item, then you can use the modelType and wildcardLabel parameters to
* return a wildcard count similar to what is done in the searchSelect component.
*
* @example
* <InfoTableItemArray @label="Roles" @displayArray={{array "test-1" "test-2" "test-3"}} />
*
* @param {string} label - used to render lowercased display text for "View all [label]."
* @param {array} displayArray - The array of data to be displayed. (In InfoTableRow this comes from the `@value` arg.) If the array length > 10, and `@doNotTruncate` is false only 5 will show with a count of the number hidden.
* @param {boolean} [isLink] - Indicates if the item should contain a link-to component. Only setup for arrays, but this could be changed if needed.
* @param {string | array} [rootRoute=vault.cluster.secrets.backend.list-root] - Tells what route the link should go to when selecting "view all". If the route requires more than one dynamic param, insert an array.
* @param {string | array} [itemRoute=vault.cluster.secrets.backend.show] - Tells what route the link should go to when selecting the individual item. If the route requires more than one dynamic param, insert an array.
* @param {string} [modelType] - Tells which model you want to query and set allOptions. Used in conjunction with the the isLink.
* @param {string} [wildcardLabel] - when you want the component to return a count on the model for options returned when using a wildcard you must provide a label of the count e.g. role. Should be singular.
* @param {string} [backend] - To specify which backend to point the link to.
* @param {boolean} [doNotTruncate=false] - Determines whether to show the View all "roles" link. Otherwise uses the ReadMore component's "See More" toggle
* @param {boolean} [renderItemName=false] - If true renders the item name instead of its id
*/
export default class InfoTableItemArray extends Component {
@service store;
@tracked allOptions = null;
@tracked itemNameById; // object is only created if renderItemName=true
@tracked fetchComplete = false;
constructor() {
super(...arguments);
assert('@label is required for InfoTableItemArray components', this.args.label);
}
get rootRoute() {
return this.args.rootRoute || 'vault.cluster.secrets.backend.list-root';
}
get itemRoute() {
return this.args.itemRoute || 'vault.cluster.secrets.backend.show';
}
get doNotTruncate() {
return this.args.doNotTruncate || false;
}
get displayArrayTruncated() {
const { displayArray } = this.args;
if (!displayArray) return null;
if (displayArray.length >= 10 && !this.args.doNotTruncate) {
// if array greater than 10 in length only display the first 5
return displayArray.slice(0, 5);
}
return displayArray;
}
get wildcardLabel() {
return this.args.wildcardLabel || '';
}
@action async fetchOptions() {
if (this.args.isLink && this.args.modelType) {
const queryOptions = this.args.backend ? { backend: this.args.backend } : {};
const modelRecords = await this.store.query(this.args.modelType, queryOptions).catch((err) => {
if (err.httpStatus === 404) {
return [];
} else {
return null;
}
});
this.allOptions = modelRecords ? modelRecords.map((record) => record.id) : null;
if (this.args.renderItemName && modelRecords) {
modelRecords.forEach(({ id, name }) => {
// create key/value pair { item-id: item-name } for each record
this.itemNameById = { ...this.itemNameById, [id]: name };
});
}
}
this.fetchComplete = true;
}
}