Skip to content

Commit 12e7fc7

Browse files
committed
feat(catalog-ui): add rename favorite button and dialog
1 parent 9df360f commit 12e7fc7

10 files changed

Lines changed: 311 additions & 90 deletions

File tree

apps/catalog-ui/docs/components/smart-filter/LinidSmartFilter.md

Lines changed: 63 additions & 56 deletions
Large diffs are not rendered by default.

apps/catalog-ui/docs/design.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,14 @@ Smart filtering component with toggle-able menu for managing active filters and
427427
"label-section": {
428428
"q-item-section": {}
429429
},
430-
"delete-section": {
430+
"item-actions-section": {
431431
"q-item-section": {},
432-
"q-btn": {}
432+
"rename-button": {
433+
"q-btn": {}
434+
},
435+
"delete-button": {
436+
"q-btn": {}
437+
}
433438
},
434439
"no-data-icon-section": {
435440
"q-item-section": {},
@@ -846,9 +851,14 @@ Page that contain table with search and filtering capabilities.
846851
"label-section": {
847852
"q-item-section": {}
848853
},
849-
"delete-section": {
854+
"item-actions-section": {
850855
"q-item-section": {},
851-
"q-btn": {}
856+
"rename-button": {
857+
"q-btn": {}
858+
},
859+
"delete-button": {
860+
"q-btn": {}
861+
}
852862
},
853863
"no-data-icon-section": {
854864
"q-item-section": {},
@@ -1163,9 +1173,14 @@ A full example showing all CatalogUI components configured together:
11631173
"label-section": {
11641174
"q-item-section": {}
11651175
},
1166-
"delete-section": {
1176+
"item-actions-section": {
11671177
"q-item-section": {},
1168-
"q-btn": {}
1178+
"rename-button": {
1179+
"q-btn": {}
1180+
},
1181+
"delete-button": {
1182+
"q-btn": {}
1183+
}
11691184
},
11701185
"no-data-icon-section": {
11711186
"q-item-section": {},

apps/catalog-ui/docs/i18n.md

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -372,18 +372,19 @@ The `FormDialog` component uses the following keys for internationalization:
372372

373373
**File:** apps/catalog-ui/src/pages/GenericTablePage.vue
374374

375-
| Key | Description | Usage | Parameters |
376-
| ---------------------------------- | ---------------------------------------------------------------------- | -------------------- | ---------- |
377-
| `[INSTANCE_ID].title` | Title displayed at the top of the page (if present) | Page header | - |
378-
| `[INSTANCE_ID].error` | Error message when data loading fails. | Page toaster | - |
379-
| `[INSTANCE_ID].seeButton` | Label for the “see details” action button | Table row action | - |
380-
| `[INSTANCE_ID].ButtonsCard` | Base translation scope for the actions card (e.g. create button label) | Page actions section | - |
381-
| `[INSTANCE_ID].GenericEntityTable` | Base translation scope for the GenericEntityTable | Page table section | - |
382-
| `[INSTANCE_ID].DeleteDialog` | Base translation scope for the delete-favorite ConfirmationDialog | Page dialog section | - |
383-
| `[INSTANCE_ID].OverrideDialog` | Base translation scope for the override-favorite FormDialog | Page dialog section | - |
384-
| `[INSTANCE_ID].CreateDialog` | Base translation scope for the create-favorite FormDialog | Page dialog section | - |
385-
| `[INSTANCE_ID].LinidSmartFilter` | Base translation scope for the LinidSmartFilter | Page search section | - |
386-
| `[INSTANCE_ID].[FIELD_LABEL]` | Label displayed for a table column header | Table column header | - |
375+
| Key | Description | Usage | Parameters |
376+
| ------------------------------------ | ---------------------------------------------------------------------- | -------------------- | ---------- |
377+
| `[INSTANCE_ID].title` | Title displayed at the top of the page (if present) | Page header | - |
378+
| `[INSTANCE_ID].error` | Error message when data loading fails. | Page toaster | - |
379+
| `[INSTANCE_ID].seeButton` | Label for the “see details” action button | Table row action | - |
380+
| `[INSTANCE_ID].ButtonsCard` | Base translation scope for the actions card (e.g. create button label) | Page actions section | - |
381+
| `[INSTANCE_ID].GenericEntityTable` | Base translation scope for the GenericEntityTable | Page table section | - |
382+
| `[INSTANCE_ID].DeleteDialog` | Base translation scope for the delete-favorite ConfirmationDialog | Page dialog section | - |
383+
| `[INSTANCE_ID].RenameFavoriteDialog` | Base translation scope for the rename-favorite FormDialog | Page dialog section | - |
384+
| `[INSTANCE_ID].OverrideDialog` | Base translation scope for the override-favorite FormDialog | Page dialog section | - |
385+
| `[INSTANCE_ID].CreateDialog` | Base translation scope for the create-favorite FormDialog | Page dialog section | - |
386+
| `[INSTANCE_ID].LinidSmartFilter` | Base translation scope for the LinidSmartFilter | Page search section | - |
387+
| `[INSTANCE_ID].[FIELD_LABEL]` | Label displayed for a table column header | Table column header | - |
387388

388389
**Example:**
389390

@@ -412,6 +413,21 @@ The `FormDialog` component uses the following keys for internationalization:
412413
"confirmLoading": "Saving..."
413414
}
414415
},
416+
"RenameFavoriteDialog": {
417+
"title": "Rename a favorite?",
418+
"content": "Enter a new name for favorite \"{label}\".",
419+
"duplicateName": "A favorite with the name \"{name}\" already exists.",
420+
"ButtonsCard": {
421+
"cancel": "Cancel",
422+
"confirm": "Rename",
423+
"confirmLoading": "Renaming..."
424+
},
425+
"fields": {
426+
"favoriteName": {
427+
"label": "Name"
428+
}
429+
}
430+
},
415431
"OverrideFavoriteDialog": {
416432
"title": "Override a favorite?",
417433
"content": "Select the favorite to replace with the current filters.",
@@ -437,6 +453,7 @@ The `FormDialog` component uses the following keys for internationalization:
437453
}
438454
},
439455
"RemoveFavoriteNotifyMessage": "The favorite '{name}' has been removed.",
456+
"RenameFavoriteNotifyMessage": "The favorite '{name}' has been renamed.",
440457
"CreateFavoriteNotifyMessage": "The favorite '{name}' has been created.",
441458
"OverrideFavoriteNotifyMessage": "The favorite '{name}' has been overwritten.",
442459
"LinidSmartFilter": {
@@ -491,6 +508,7 @@ The `FormDialog` component uses the following keys for internationalization:
491508
| `[INSTANCE_ID].LinidSmartFilter.LinidFavoritePanel.noData` | No data panel section | No data label | - |
492509
| `[INSTANCE_ID].LinidSmartFilter.LinidFavoritePanel.createFavorite` | Label for create button | QBtn label | - |
493510
| `[INSTANCE_ID].LinidSmartFilter.LinidFavoritePanel.overrideFavorite` | Label for override button | QBtn label | - |
511+
| `[INSTANCE_ID].LinidSmartFilter.LinidFavoritePanel.renameButton` | Label for rename button (optional, defaults to empty string) | QBtn label | - |
494512
| `[INSTANCE_ID].LinidSmartFilter.LinidFavoritePanel.deleteButton` | Label for delete button (optional, defaults to empty string) | QBtn label | - |
495513
| `[INSTANCE_ID].LinidSmartFilter.TreeSearchFilterPanel.searchButton` | Search button label | QBtn label | - |
496514
| `[INSTANCE_ID].LinidSmartFilter.TreeSearchFilterPanel.errorLoadingData` | Error message when failing to load tree data | Notification message | - |
@@ -534,6 +552,7 @@ The `FormDialog` component uses the following keys for internationalization:
534552
"noData": "No available favorites",
535553
"createFavorite": "Create Favorite",
536554
"overrideFavorite": "Override Favorite",
555+
"renameButton": "Rename",
537556
"deleteButton": "Delete"
538557
},
539558
"TextSearchFilterPanel": {
@@ -676,6 +695,7 @@ export default {
676695
noData: 'No available favorites',
677696
createFavorite: 'Create Favorite',
678697
overrideFavorite: 'Override Favorite',
698+
renameButton: 'Rename',
679699
deleteButton: 'Delete',
680700
},
681701
TextSearchFilterPanel: {
@@ -810,6 +830,21 @@ export default {
810830
confirmLoading: 'Saving...',
811831
},
812832
},
833+
RenameFavoriteDialog: {
834+
title: 'Rename a favorite?',
835+
content: 'Enter a new name for favorite "{label}".',
836+
duplicateName: 'A favorite with the name "{name}" already exists.',
837+
ButtonsCard: {
838+
cancel: 'Cancel',
839+
confirm: 'Rename',
840+
confirmLoading: 'Renaming...',
841+
},
842+
fields: {
843+
favoriteName: {
844+
label: 'Name',
845+
},
846+
},
847+
},
813848
OverrideFavoriteDialog: {
814849
title: 'Override a favorite?',
815850
content: 'Select the favorite to replace with the current filters.',
@@ -835,6 +870,7 @@ export default {
835870
},
836871
},
837872
RemoveFavoriteNotifyMessage: "The favorite '{name}' has been removed.",
873+
RenameFavoriteNotifyMessage: "The favorite '{name}' has been renamed.",
838874
CreateFavoriteNotifyMessage: "The favorite '{name}' has been created.",
839875
OverrideFavoriteNotifyMessage: "The favorite '{name}' has been overwritten.",
840876
LinidSmartFilter: {
@@ -856,6 +892,7 @@ export default {
856892
noData: 'No available favorites',
857893
createFavorite: 'Create Favorite',
858894
overrideFavorite: 'Override Favorite',
895+
renameButton: 'Rename',
859896
deleteButton: 'Delete',
860897
},
861898
TextSearchFilterPanel: {

apps/catalog-ui/docs/pages/GenericTablePage.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,18 @@ Each active filter is serialized to a query param using `filter.toString()`, key
195195
- `ButtonsCard.create`
196196
- `DeleteFavoriteDialog.title` — title of the delete-favorite confirmation dialog
197197
- `DeleteFavoriteDialog.content` — body of the delete-favorite confirmation dialog (`{label}` placeholder available)
198+
- `RenameFavoriteDialog.title` — title of the rename-favorite form dialog
199+
- `RenameFavoriteDialog.content` — body of the rename-favorite form dialog (`{label}` placeholder available)
200+
- `RenameFavoriteDialog.duplicateName` — error message when the chosen name is already used by another favorite (`{name}` placeholder available)
198201
- `OverrideFavoriteDialog.title` — title of the override-favorite form dialog
199202
- `OverrideFavoriteDialog.content` — body of the override-favorite form dialog
200203
- `CreateFavoriteDialog.title` — title of the create-favorite form dialog
201204
- `CreateFavoriteDialog.content` — body of the create-favorite form dialog
202-
- `RemoveFavoriteNotifyMessage` — notification message displayed when a favorite filter set is successfully deleted
203-
- `CreateFavoriteNotifyMessage` — notification message displayed when a new favorite filter set is successfully created
204-
- `OverrideFavoriteNotifyMessage` — notification message displayed when an existing favorite filter set is successfully updated with new filters
205+
- `CreateFavoriteDialog.duplicateName` — error message when the chosen name is already used by another favorite (`{name}` placeholder available)
206+
- `RemoveFavoriteNotifyMessage` — notification message displayed when a favorite filter set is successfully deleted (`{name}` placeholder available)
207+
- `RenameFavoriteNotifyMessage` — notification message displayed when a favorite filter set is successfully renamed (`{name}` placeholder available)
208+
- `CreateFavoriteNotifyMessage` — notification message displayed when a new favorite filter set is successfully created (`{name}` placeholder available)
209+
- `OverrideFavoriteNotifyMessage` — notification message displayed when an existing favorite filter set is successfully updated with new filters (`{name}` placeholder available)
205210

206211
---
207212

apps/catalog-ui/src/components/smart-filter/LinidFavoritePanel.vue

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,27 @@
8282
{{ favorite.label }}
8383
</q-item-section>
8484
<q-item-section
85-
v-bind="uiProps.deleteSection"
86-
class="row items-end"
85+
v-bind="uiProps.itemActionsSection"
86+
class="items-end linid-favorite-panel--item-actions-section"
8787
>
88-
<q-btn
89-
v-bind="uiProps.deleteButton"
90-
:label="translateOrDefault('', 'deleteButton')"
91-
class="delete-button"
92-
:data-cy="`button_delete_${index}`"
93-
@click.stop="emit('delete', favorite)"
94-
/>
88+
<div
89+
class="row justify-end linid-favorite-panel--item-actions-container"
90+
>
91+
<q-btn
92+
v-bind="uiProps.renameButton"
93+
:label="translateOrDefault('', 'renameButton')"
94+
class="rename-button"
95+
:data-cy="`button_rename_${index}`"
96+
@click.stop="emit('rename', favorite)"
97+
/>
98+
<q-btn
99+
v-bind="uiProps.deleteButton"
100+
:label="translateOrDefault('', 'deleteButton')"
101+
class="delete-button"
102+
:data-cy="`button_delete_${index}`"
103+
@click.stop="emit('delete', favorite)"
104+
/>
105+
</div>
95106
</q-item-section>
96107
</q-item>
97108

@@ -171,12 +182,16 @@ const uiProps = computed<LinidFavoritePanelUIProps>(() => ({
171182
`${contentUiNamespace}.no-data-label-section`,
172183
'q-item-section'
173184
),
174-
deleteSection: ui<LinidQItemSectionProps>(
175-
`${contentUiNamespace}.delete-section`,
185+
itemActionsSection: ui<LinidQItemSectionProps>(
186+
`${contentUiNamespace}.item-actions-section`,
176187
'q-item-section'
177188
),
189+
renameButton: ui<LinidQBtnProps>(
190+
`${contentUiNamespace}.item-actions-section.rename-button`,
191+
'q-btn'
192+
),
178193
deleteButton: ui<LinidQBtnProps>(
179-
`${contentUiNamespace}.delete-section`,
194+
`${contentUiNamespace}.item-actions-section.delete-button`,
180195
'q-btn'
181196
),
182197
createButton: ui<LinidQBtnProps>(

apps/catalog-ui/src/components/smart-filter/LinidSmartFilter.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
:i18n-scope="localI18nScope"
120120
data-cy="linid-smart-favorite-panel"
121121
@apply="(data) => emit('apply:favorite', data)"
122+
@rename="(data) => emit('rename:favorite', data)"
122123
@delete="(data) => emit('delete:favorite', data)"
123124
@create="emit('create:favorite')"
124125
@override="emit('override:favorite')"

apps/catalog-ui/src/pages/GenericTablePage.vue

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
:is-menu-persistent="isSmartFilterMenuPersistent"
5353
@update:filters="onFiltersChange"
5454
@apply:favorite="onFavoriteApply"
55+
@rename:favorite="openRenameFavoriteDialog"
5556
@delete:favorite="openDeleteFavoriteDialog"
5657
@override:favorite="openOverrideFavoriteDialog"
5758
@create:favorite="openCreateFavoriteDialog"
@@ -311,6 +312,64 @@ function openDeleteFavoriteDialog(favorite: LinidFilterSet): void {
311312
});
312313
}
313314
315+
/**
316+
* Opens a form dialog to rename a favorite filter set.
317+
* @param favorite - The favorite filter set to rename.
318+
*/
319+
function openRenameFavoriteDialog(favorite: LinidFilterSet): void {
320+
uiEventSubject.next({
321+
key: 'form',
322+
data: {
323+
type: 'open',
324+
title: t('RenameFavoriteDialog.title'),
325+
content: t('RenameFavoriteDialog.content', { label: favorite.label }),
326+
uiNamespace: `${uiNamespace.value}.rename-favorite-dialog`,
327+
i18nScope: `${i18nScope.value}.RenameFavoriteDialog`,
328+
formFields: [
329+
{
330+
name: 'favoriteName',
331+
type: 'String',
332+
input: 'Text',
333+
required: true,
334+
inputSettings: {},
335+
},
336+
],
337+
// eslint-disable-next-line jsdoc/require-jsdoc
338+
onSubmit: (formData: { favoriteName: string }) => {
339+
const trimmedFavoriteName = formData.favoriteName.trim();
340+
if (favorites.value.some((fav) => fav.label === trimmedFavoriteName)) {
341+
Notify({
342+
type: 'negative',
343+
message: t('RenameFavoriteDialog.duplicateName', {
344+
name: trimmedFavoriteName,
345+
}),
346+
});
347+
return;
348+
}
349+
350+
saveUserPreference(
351+
`${favoritesBaseConfigurationKey.value}${favorite.id}`,
352+
JSON.stringify({
353+
id: favorite.id,
354+
label: trimmedFavoriteName,
355+
value: new LinidFilterSet(
356+
favorite.id,
357+
trimmedFavoriteName,
358+
favorite.filters
359+
).toString(),
360+
})
361+
);
362+
Notify({
363+
type: 'positive',
364+
message: t('RenameFavoriteNotifyMessage', {
365+
name: trimmedFavoriteName,
366+
}),
367+
});
368+
},
369+
},
370+
});
371+
}
372+
314373
/**
315374
* Opens a confirmation dialog to override an existing favorite filter set with the current filters.
316375
*/

apps/catalog-ui/src/types/linidFavoritePanel.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ export interface LinidFavoritePanelUIProps {
9797
/**
9898
* The UI properties for the delete item section.
9999
*/
100-
deleteSection: LinidQItemSectionProps;
100+
itemActionsSection: LinidQItemSectionProps;
101101
/**
102102
* The UI properties for the delete button.
103103
*/
104104
deleteButton: LinidQBtnProps;
105+
/**
106+
* The UI properties for the rename button.
107+
*/
108+
renameButton: LinidQBtnProps;
105109
/**
106110
* The UI properties for the create button.
107111
*/
@@ -118,6 +122,7 @@ export interface LinidFavoritePanelUIProps {
118122
export type LinidFavoritePanelOutputs = {
119123
(e: 'apply', favorite: LinidFilterSet): void;
120124
(e: 'delete', favorite: LinidFilterSet): void;
125+
(e: 'rename', favorite: LinidFilterSet): void;
121126
(e: 'create'): void;
122127
(e: 'override'): void;
123128
};

apps/catalog-ui/src/types/smartFilter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export interface LinidSmartFilterProps extends CommonComponentProps {
6666
export type LinidSmartFilterOutputs = {
6767
(e: 'update:filters', filters: LinidFilter[]): void;
6868
(e: 'apply:favorite', favorite: LinidFilterSet): void;
69+
(e: 'rename:favorite', favorite: LinidFilterSet): void;
6970
(e: 'delete:favorite', favorite: LinidFilterSet): void;
7071
(e: 'create:favorite'): void;
7172
(e: 'override:favorite'): void;

0 commit comments

Comments
 (0)