@cccsaurora/howler-ui 3.1.0-dev.1649 → 3.1.0-dev.1655

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -188,14 +188,18 @@ const RecordContextMenu = ({ children, getSelectedId, Component }) => {
188
188
  onClick: () => executeAction(action.action_id, `howler.id:(${records.map(r => r.howler.id).join(' OR ')})`)
189
189
  }))
190
190
  });
191
- if (!isEmpty(template?.keys ?? []) && setQuery) {
191
+ const filterKeys = Array.from(new Set([
192
+ ...(template?.keys ?? []),
193
+ ...Object.keys(record.howler.outline ?? {}).map(key => `howler.outline.${key}`)
194
+ ]));
195
+ if (!isEmpty(filterKeys) && setQuery) {
192
196
  result.push({ kind: 'divider', id: 'filter-divider' });
193
197
  result.push({
194
198
  kind: 'submenu',
195
199
  id: 'excludes',
196
200
  icon: _jsx(RemoveCircleOutline, {}),
197
201
  label: t('hit.panel.exclude'),
198
- items: (template?.keys ?? []).flatMap(key => {
202
+ items: filterKeys.flatMap(key => {
199
203
  let newQuery = '';
200
204
  if (query !== DEFAULT_QUERY) {
201
205
  newQuery = `(${query}) AND `;
@@ -225,7 +229,7 @@ const RecordContextMenu = ({ children, getSelectedId, Component }) => {
225
229
  id: 'includes',
226
230
  icon: _jsx(AddCircleOutline, {}),
227
231
  label: t('hit.panel.include'),
228
- items: (template?.keys ?? []).flatMap(key => {
232
+ items: filterKeys.flatMap(key => {
229
233
  let newQuery = `(${query}) AND `;
230
234
  const value = get(record, key);
231
235
  if (!value) {
@@ -648,7 +648,7 @@ describe('HitContextMenu', () => {
648
648
  expect(mockParameterContext.setQuery).toHaveBeenCalledWith('(howler.status:open) AND -howler.detection:"Test Detection"');
649
649
  });
650
650
  });
651
- it('should not render exclusion menu when template has no keys', async () => {
651
+ it('should render outline fields in the exclusion menu when template has no keys', async () => {
652
652
  mockGetMatchingTemplate.mockResolvedValue(createMockTemplate({
653
653
  keys: []
654
654
  }));
@@ -660,7 +660,13 @@ describe('HitContextMenu', () => {
660
660
  await waitFor(() => {
661
661
  expect(screen.getByRole('menu')).toBeInTheDocument();
662
662
  });
663
- expect(screen.queryByText('Exclude By')).toBeNull();
663
+ expect(screen.getByText('Exclude By')).toBeInTheDocument();
664
+ act(() => {
665
+ fireEvent.mouseEnter(screen.getByText('Exclude By'));
666
+ });
667
+ await waitFor(() => {
668
+ expect(screen.getByTestId('excludes-submenu').textContent).toContain('howler.outline.indicators');
669
+ });
664
670
  });
665
671
  it('should skip null field values in exclusion menu', async () => {
666
672
  act(() => {
@@ -777,7 +783,7 @@ describe('HitContextMenu', () => {
777
783
  expect(mockParameterContext.setQuery).toHaveBeenCalledWith('(howler.status:open) AND howler.detection:"Test Detection"');
778
784
  });
779
785
  });
780
- it('should not render inclusion menu when template has no keys', async () => {
786
+ it('should render outline fields in the inclusion menu when template has no keys', async () => {
781
787
  mockGetMatchingTemplate.mockResolvedValue(createMockTemplate({
782
788
  keys: []
783
789
  }));
@@ -789,7 +795,16 @@ describe('HitContextMenu', () => {
789
795
  await waitFor(() => {
790
796
  expect(screen.getByRole('menu')).toBeInTheDocument();
791
797
  });
792
- expect(screen.queryByText('Include By')).toBeNull();
798
+ act(() => {
799
+ fireEvent.mouseEnter(screen.getByText('Include By'));
800
+ });
801
+ await waitFor(() => {
802
+ expect(screen.getByTestId('includes-submenu').textContent).toContain('howler.outline.indicators');
803
+ });
804
+ await act(async () => {
805
+ await user.click(screen.getByText('howler.outline.indicators'));
806
+ });
807
+ expect(mockParameterContext.setQuery).toHaveBeenCalledWith(expect.stringContaining('howler.outline.indicators:("a" OR "b" OR "c")'));
793
808
  });
794
809
  it('should skip null field values in inclusion menu', async () => {
795
810
  act(() => {
@@ -895,7 +910,7 @@ describe('HitContextMenu', () => {
895
910
  });
896
911
  expect(screen.queryByRole('menu')).toBeInTheDocument();
897
912
  });
898
- it('should not render exclusion menu when template is null', async () => {
913
+ it('should render exclusion menu for outline fields when template is null', async () => {
899
914
  mockGetMatchingTemplate.mockResolvedValue(null);
900
915
  rerender(_jsx(Wrapper, { children: _jsx(RecordContextMenu, { getSelectedId: mockGetSelectedId, children: _jsx("div", { children: "Test Content" }) }) }));
901
916
  act(() => {
@@ -905,11 +920,9 @@ describe('HitContextMenu', () => {
905
920
  await waitFor(() => {
906
921
  expect(screen.getByRole('menu')).toBeInTheDocument();
907
922
  });
908
- await waitFor(() => {
909
- expect(screen.queryByText('Exclude By')).toBeNull();
910
- });
923
+ expect(screen.getByText('Exclude By')).toBeInTheDocument();
911
924
  });
912
- it('should not render inclusion menu when template is null', async () => {
925
+ it('should render inclusion menu for outline fields when template is null', async () => {
913
926
  mockGetMatchingTemplate.mockResolvedValue(null);
914
927
  rerender(_jsx(Wrapper, { children: _jsx(RecordContextMenu, { getSelectedId: mockGetSelectedId, children: _jsx("div", { children: "Test Content" }) }) }));
915
928
  act(() => {
@@ -919,9 +932,7 @@ describe('HitContextMenu', () => {
919
932
  await waitFor(() => {
920
933
  expect(screen.getByRole('menu')).toBeInTheDocument();
921
934
  });
922
- await waitFor(() => {
923
- expect(screen.queryByText('Include By')).toBeNull();
924
- });
935
+ expect(screen.getByText('Include By')).toBeInTheDocument();
925
936
  });
926
937
  it('should handle API failure gracefully', async () => {
927
938
  mockDispatchApi.mockResolvedValue(null);
package/package.json CHANGED
@@ -97,7 +97,7 @@
97
97
  "url": "https://github.com/CybercentreCanada/howler"
98
98
  },
99
99
  "type": "module",
100
- "version": "3.1.0-dev.1649",
100
+ "version": "3.1.0-dev.1655",
101
101
  "exports": {
102
102
  "./i18n": "./i18n.js",
103
103
  "./index.css": "./index.css",