diff --git a/Gemfile.lock b/Gemfile.lock index 99d2268..a72fc52 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - diver_down (0.0.1.alpha1) + diver_down (0.0.1.alpha2) activesupport (>= 7.0.0) rack-contrib (>= 2.3.0) diff --git a/frontend/pages/Home/components/DefinitionList/ConfigureSearchOptionsDialog.tsx b/frontend/pages/Home/components/DefinitionList/ConfigureSearchOptionsDialog.tsx index 92d3262..40a00e0 100644 --- a/frontend/pages/Home/components/DefinitionList/ConfigureSearchOptionsDialog.tsx +++ b/frontend/pages/Home/components/DefinitionList/ConfigureSearchOptionsDialog.tsx @@ -8,6 +8,7 @@ export type SearchDefinitionsOptions = { title: string source: string folding: boolean + definitionGroup: string } type Props = { @@ -38,6 +39,13 @@ export const ConfigureSearchOptionsDialog: React.FC = ({ onClickClose() } + const onChangeDefinitionGroup = useCallback( + (event: React.ChangeEvent) => { + setTemporarySearchDefinitionsOptions((prev) => ({ ...prev, definitionGroup: event.target.value })) + }, + [setTemporarySearchDefinitionsOptions], + ) + const onChangeTitle = useCallback( (event: React.ChangeEvent) => { setTemporarySearchDefinitionsOptions((prev) => ({ ...prev, title: event.target.value })) @@ -77,6 +85,15 @@ export const ConfigureSearchOptionsDialog: React.FC = ({

Configure settings related to the display of definitions.

+ + + + diff --git a/frontend/pages/Home/components/DefinitionList/DefinitionList.tsx b/frontend/pages/Home/components/DefinitionList/DefinitionList.tsx index 2c7b906..5962197 100644 --- a/frontend/pages/Home/components/DefinitionList/DefinitionList.tsx +++ b/frontend/pages/Home/components/DefinitionList/DefinitionList.tsx @@ -20,12 +20,13 @@ type DialogType = 'configureSearchOptionsDiaglog' export const DefinitionList: FC = ({ selectedDefinitionIds, setSelectedDefinitionIds }) => { const [visibleDialog, setVisibleDialog] = useState(null) const [searchDefinitionsOptions, setSearchDefinitionsOptions] = useLocalStorage( - 'Home-DefinitionList-SearchDefinitionOptions', - { title: '', source: '', folding: false }, + 'Home-DefinitionList-SearchDefinitionOptions-v1', + { definitionGroup: '', title: '', source: '', folding: false }, ) const [foldingSection, setFoldingSection] = useState(false) const { isLoading, definitions, isValidating, setSize, isReachingEnd } = useDefinitionList({ + definitionGroup: searchDefinitionsOptions.definitionGroup, title: searchDefinitionsOptions.title, source: searchDefinitionsOptions.source, }) diff --git a/frontend/repositories/definitionListRepository.ts b/frontend/repositories/definitionListRepository.ts index 5783d7f..90d661e 100644 --- a/frontend/repositories/definitionListRepository.ts +++ b/frontend/repositories/definitionListRepository.ts @@ -21,7 +21,10 @@ type DefinitionsResponse = { export const PER = 100 -export const useDefinitionList = (query: { title: string; source: string }, keepPreviousData: boolean = false) => { +export const useDefinitionList = ( + query: { definitionGroup: string; title: string; source: string }, + keepPreviousData: boolean = false, +) => { const getKey = (pageIndex: number, previousPageData: DefinitionReponse[] | null) => { if (previousPageData && previousPageData.length === 0) { return null @@ -29,7 +32,9 @@ export const useDefinitionList = (query: { title: string; source: string }, keep const params = { per: PER, page: pageIndex + 1, - ...query, + definition_group: query.definitionGroup, + title: query.title, + source: query.source, } return `${path.api.definitions.index()}?${stringify(params)}` diff --git a/lib/diver_down/web.rb b/lib/diver_down/web.rb index 53c1ab1..db7d304 100644 --- a/lib/diver_down/web.rb +++ b/lib/diver_down/web.rb @@ -45,7 +45,8 @@ def call(env) page: request.params['page']&.to_i || 1, per: request.params['per']&.to_i || 100, title: request.params['title'] || '', - source: request.params['source'] || '' + source: request.params['source'] || '', + definition_group: request.params['definition_group'] || '' ) in ['GET', %r{\A/api/sources\.json\z}] action.sources diff --git a/lib/diver_down/web/action.rb b/lib/diver_down/web/action.rb index 8005e5d..274913c 100644 --- a/lib/diver_down/web/action.rb +++ b/lib/diver_down/web/action.rb @@ -119,8 +119,9 @@ def module(module_names) # @param per [Integer] # @param title [String] # @param source [String] - def definitions(page:, per:, title:, source:) - definition_enumerator = DiverDown::Web::DefinitionEnumerator.new(@store, title:, source:) + # @param definition_group [String] + def definitions(page:, per:, title:, source:, definition_group:) + definition_enumerator = DiverDown::Web::DefinitionEnumerator.new(@store, title:, source:, definition_group:) definitions, pagination = paginate(definition_enumerator, page, per) json( diff --git a/lib/diver_down/web/definition_enumerator.rb b/lib/diver_down/web/definition_enumerator.rb index 9edbbef..d37a624 100644 --- a/lib/diver_down/web/definition_enumerator.rb +++ b/lib/diver_down/web/definition_enumerator.rb @@ -7,10 +7,12 @@ class DefinitionEnumerator # @param store [DiverDown::Definition::Store] # @param query [String] - def initialize(store, title: '', source: '') + # @param definition_group [String] + def initialize(store, title: '', source: '', definition_group: '') @store = store @title = title @source = source + @definition_group = definition_group end # @yield [parent_bit_id, bit_id, definition] @@ -47,6 +49,10 @@ def match_definition?(definition) matched &&= definition.sources.any? { _1.source_name.include?(@source) } end + unless @definition_group.empty? + matched &&= definition.definition_group.to_s.include?(@definition_group) + end + matched end end diff --git a/spec/diver_down/web/definition_enumerator_spec.rb b/spec/diver_down/web/definition_enumerator_spec.rb index 4fc3f63..2c97507 100644 --- a/spec/diver_down/web/definition_enumerator_spec.rb +++ b/spec/diver_down/web/definition_enumerator_spec.rb @@ -26,6 +26,45 @@ ) end + describe 'with definition_group' do + def assert_query(store, definition_group, expected) + actual = described_class.new(store, definition_group:).each.to_a + expect(actual).to eq(expected), -> { + "definition_group: #{definition_group.inspect}\n" \ + "expected: #{expected.inspect}\n" \ + "actual: #{actual.inspect}" + } + end + + it 'filters by definition_group' do + store = DiverDown::Web::DefinitionStore.new + + definition_1 = DiverDown::Definition.new( + definition_group: 'group_1', + sources: [ + DiverDown::Definition::Source.new( + source_name: 'a.rb' + ), + ] + ) + definition_2 = DiverDown::Definition.new( + definition_group: 'group_2', + sources: [ + DiverDown::Definition::Source.new( + source_name: 'b.rb' + ), + ] + ) + + store.set(definition_1, definition_2) + + assert_query store, 'unknown', [] + assert_query store, 'group', [definition_1, definition_2] + assert_query store, 'group_1', [definition_1] + assert_query store, 'group_2', [definition_2] + end + end + describe 'with title' do def assert_query(store, title, expected) actual = described_class.new(store, title:).each.to_a diff --git a/spec/diver_down/web_spec.rb b/spec/diver_down/web_spec.rb index bc15d49..37e0aa0 100644 --- a/spec/diver_down/web_spec.rb +++ b/spec/diver_down/web_spec.rb @@ -184,6 +184,47 @@ def assert_source(source, expected_ids) assert_source 'b.', [definition_2_id] end end + + describe 'definition_group' do + def assert_definition_group(definition_group, expected_ids) + get "/api/definitions.json?definition_group=#{definition_group}" + + definitions = JSON.parse(last_response.body)['definitions'] + ids = definitions.map { _1['id'] } + + expect(ids).to match_array(expected_ids), -> { + "definition_group: #{definition_group.inspect}\n" \ + "expected_ids: #{expected_ids.inspect}\n" \ + "actual_ids: #{ids.inspect}" + } + end + + it 'filters definitions by definition_group=value' do + definition_1 = DiverDown::Definition.new( + definition_group: 'group_1', + sources: [ + DiverDown::Definition::Source.new( + source_name: 'a.rb' + ), + ] + ) + definition_2 = DiverDown::Definition.new( + definition_group: 'group_2', + sources: [ + DiverDown::Definition::Source.new( + source_name: 'b.rb' + ), + ] + ) + + definition_1_id, definition_2_id = store.set(definition_1, definition_2) + + assert_definition_group 'unknown', [] + assert_definition_group 'group', [definition_1_id, definition_2_id] + assert_definition_group 'group_1', [definition_1_id] + assert_definition_group 'group_2', [definition_2_id] + end + end end describe 'GET /api/initialization_status.json' do