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

👻 Refactor tags table to remove deprecated legacy table dep #1806

Merged
merged 3 commits into from
Apr 5, 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
5 changes: 4 additions & 1 deletion client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
"blockedDeleteTarget": "Cannot delete {{what}} because it is associated with a target.",
"defaultBlockedDelete": "Cannot delete {{what}} because it is associated with another object.",
"cannotDeleteApplicationsAssignedToMigrationWave": "Cannot delete applications that are assigned to a migration wave.",
"cannotDeleteNonEmptyTagCategory": "Cannot delete a tag category that contains tags.",
"continueConfirmation": "Yes, continue",
"copyAssessmentAndReviewBody": "Some of the selected target applications have an in-progress or complete assessment/review. By continuing, the existing assessment(s)/review(s) will be replaced by the copied assessment/review. Do you wish to continue?",
"copyAssessmentAndReviewQuestion": "Copy assessment and review?",
Expand Down Expand Up @@ -220,7 +221,9 @@
"toTagApplication": "Either no tags exist yet or you may not have permission to view any. If you have permission, try creating a new custom tag.",
"unsavedChanges": "Are you sure you want to close the assessment? Any unsaved changes will be lost.",
"noAnswers": "Are you sure you want to close the assessment? There are no answers to save.",
"unlinkTicket": "Unlink from Jira"
"unlinkTicket": "Unlink from Jira",
"noTagsAvailable": "No tags available",
"noAssociatedTags": "This tag category has no associated tags."
},
"proposedActions": {
"refactor": "Refactor",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Tag, TagCategory } from "@app/api/models";
import { COLOR_HEX_VALUES_BY_NAME } from "@app/Constants";
import { LabelCustomColor } from "@app/components/LabelCustomColor";

export const getTagCategoryFallbackColor = (category?: TagCategory) => {
export const getTagCategoryFallbackColor = (category?: TagCategory | null) => {
if (!category?.id) return COLOR_HEX_VALUES_BY_NAME.gray;
const colorValues = Object.values(COLOR_HEX_VALUES_BY_NAME);
return colorValues[category?.id % colorValues.length];
Expand Down
88 changes: 20 additions & 68 deletions client/src/app/pages/controls/tags/components/tag-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,101 +8,53 @@ import {
Tbody,
Td,
ActionsColumn,
IAction,
cellWidth,
ICell,
IRow,
IRowData,
} from "@patternfly/react-table";
import { Tag, TagCategory } from "@app/api/models";
import "./tag-table.css";

const ENTITY_FIELD = "entity";

const getRow = (rowData: IRowData): Tag => {
return rowData[ENTITY_FIELD];
};

export interface TabTableProps {
tagCategory: TagCategory;
onEdit: (tag: Tag) => void;
onDelete: (tag: Tag) => void;
}

export const TagTable: React.FC<TabTableProps> = ({
tagCategory: tagCategory,
tagCategory,
onEdit,
onDelete,
}) => {
const { t } = useTranslation();

const columns: ICell[] = [
{
title: t("terms.tagName"),
transforms: [cellWidth(100)],
cellFormatters: [],
props: {
className: "columnPadding",
},
},
];

const rows: IRow[] = [];
(tagCategory.tags || [])
.sort((a, b) => a.name.localeCompare(b.name))
.forEach((item) => {
rows.push({
[ENTITY_FIELD]: item,
noPadding: true,
cells: [
{
title: item.name,
},
],
});
});

const editRow = (row: Tag) => {
onEdit(row);
};

const deleteRow = (row: Tag) => {
onDelete(row);
};

const defaultActions = (tag: IRowData): IAction[] => [
{
title: t("actions.edit"),
onClick: () => editRow(getRow(tag)),
},
{
title: t("actions.delete"),
onClick: () => deleteRow(getRow(tag)),
},
];

return (
<Table borders={false} aria-label="Tag table" variant="compact" isNested>
<Thead noWrap>
<Tr>
<Th>{t("terms.tagName")}</Th>
<Td></Td>
<Td />
</Tr>
</Thead>
<Tbody>
{rows.map((row: IRow) => {
const rowActions = defaultActions(row);
return (
<Tr>
{row.cells?.map((cell: any) => (
<Td>{cell.title}</Td>
))}
{(tagCategory.tags || [])
.sort((a, b) => a.name.localeCompare(b.name))
Copy link
Member

Choose a reason for hiding this comment

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

Another place to use localeNumericCompare()

FWIW, localeNumbericCompare() could be changed a bit to have the locale be defaulted to "i18n.language" and ignore that part here...(could also be another PR)

/**
 * Uses native string localCompare method with numeric option enabled.
 *
 * @param locale to be used by string compareFn
 */
export const localeNumericCompare = (
  a: string,
  b: string,
  locale: string = i18n.language
): number => a.localeCompare(b, locale, { numeric: true });

Copy link
Collaborator

Choose a reason for hiding this comment

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

I vote for a small nice PR!

Copy link
Member Author

Choose a reason for hiding this comment

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

.map((tag) => (
<Tr key={tag.name}>
<Td>{tag.name}</Td>
<Td isActionCell>
{rowActions && <ActionsColumn items={rowActions} />}
<ActionsColumn
items={[
{
title: t("actions.edit"),
onClick: () => onEdit(tag),
},
{
title: t("actions.delete"),
onClick: () => onDelete(tag),
},
]}
/>
</Td>
</Tr>
);
})}
))}
</Tbody>
</Table>
);
Expand Down
Loading
Loading