Skip to content

Commit

Permalink
Merge pull request #2318 from DamnClin/modules-filter
Browse files Browse the repository at this point in the history
Simple filter for modules
  • Loading branch information
pascalgrimaud authored Jun 30, 2022
2 parents 1e6d06e + 047c2e4 commit b6ccdac
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 40 deletions.
40 changes: 35 additions & 5 deletions src/main/webapp/app/module/primary/modules/Modules.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AlertBus } from '@/common/domain/alert/AlertBus';
import { Loader } from '@/loader/primary/Loader';
import { Category } from '@/module/domain/Category';
import { Module } from '@/module/domain/Module';
import { ModuleProperty } from '@/module/domain/ModuleProperty';
import { Modules } from '@/module/domain/Modules';
Expand All @@ -12,8 +13,9 @@ export default defineComponent({
const alertBus = inject('alertBus') as AlertBus;
const modules = inject('modules') as ModulesRepository;

const modulesContent = reactive({
content: Loader.loading<Modules>(),
const applicationModules = reactive({
all: Loader.loading<Modules>(),
displayed: Loader.loading<Modules>(),
});

const applicationInProgress = ref(false);
Expand All @@ -22,7 +24,10 @@ export default defineComponent({
const moduleProperties = ref(new Map<string, string | number | boolean>());

onMounted(() => {
modules.list().then(response => modulesContent.content.loaded(response));
modules.list().then(response => {
applicationModules.all.loaded(response);
applicationModules.displayed.loaded(response);
});
});

const selectModule = (slug: string): void => {
Expand Down Expand Up @@ -78,12 +83,36 @@ export default defineComponent({
};

const getModule = (slug: string): Module => {
return modulesContent.content
return applicationModules.all
.value()
.categories.flatMap(category => category.modules)
.find(module => module.slug === slug)!;
};

const filter = (search: string): void => {
applicationModules.displayed.loaded({ categories: filterCategories(search.toLowerCase()) });
};

const filterCategories = (search: string): Category[] => {
return applicationModules.all
.value()
.categories.map(category => toFilteredCategory(category, search))
.filter(category => category.modules.length !== 0);
};

const toFilteredCategory = (category: Category, search: string): Category => {
return {
name: category.name,
modules: category.modules.filter(module => {
return contains(module.description, search) || contains(module.slug, search);
}),
};
};

const contains = (value: string, search: string): boolean => {
return value.toLowerCase().indexOf(search) !== -1;
};

const applyModule = (module: string): void => {
applicationInProgress.value = true;

Expand All @@ -105,7 +134,7 @@ export default defineComponent({
};

return {
content: modulesContent.content,
content: applicationModules.displayed,
folderPath,
selectModule,
selectedModule,
Expand All @@ -116,6 +145,7 @@ export default defineComponent({
mandatoryProperties,
optionalProperties,
moduleProperties,
filter,
applyModule,
applicationInProgress,
};
Expand Down
81 changes: 47 additions & 34 deletions src/main/webapp/app/module/primary/modules/Modules.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,48 +71,61 @@ <h2>Modules</h2>
</aside>

<div class="jhipster-modules-list">
<div v-for="category in content.value().categories">
<div>
<h2 class="jhipster-module-category--name">{{ category.name }}</h2>
<div v-for="module in category.modules" class="jhipster-module">
<div
tabindex="3"
class="jhipster-module--content"
@click="selectModule(module.slug)"
@keyup.enter="selectModule(module.slug); $refs.folderPathInput.focus()"
:data-selector="`${module.slug}-module-content`"
>
<div class="jhipster-module--slug">{{ module.slug }}</div>
<div class="jhipster-module--description">{{ module.description}}</div>
<div class="jhipster-modules-list--search">
<input
tabindex="3"
type="text"
class="jhipster-modules-list--search-field"
placeholder="Filter"
data-selector="modules-filter-field"
@input="filter($event.target.value)"
/>
</div>

<div class="jhipster-module--properties">
<div v-for="property in mandatoryProperties(module.slug)" class="jhipster-module--property">
<div class="jhipster-module--property-key">{{ property.key }}</div>
<div class="jhipster-module--property-value" :data-selector="`module-${module.slug}-${property.key}-property-value`">
{{ moduleProperties.get(property.key) }}
<div class="jhipster-modules-list--categories">
<div v-for="category in content.value().categories">
<div>
<h2 class="jhipster-module-category--name">{{ category.name }}</h2>
<div v-for="module in category.modules" class="jhipster-module">
<div
tabindex="4"
class="jhipster-module--content"
@click="selectModule(module.slug)"
@keyup.enter="selectModule(module.slug); $refs.folderPathInput.focus()"
:data-selector="`${module.slug}-module-content`"
>
<div class="jhipster-module--slug">{{ module.slug }}</div>
<div class="jhipster-module--description">{{ module.description}}</div>

<div class="jhipster-module--properties">
<div v-for="property in mandatoryProperties(module.slug)" class="jhipster-module--property">
<div class="jhipster-module--property-key">{{ property.key }}</div>
<div class="jhipster-module--property-value" :data-selector="`module-${module.slug}-${property.key}-property-value`">
{{ moduleProperties.get(property.key) }}
</div>
</div>
</div>
</div>

<div class="jhipster-module--properties">
<div v-for="property in optionalProperties(module.slug)" class="jhipster-module--property">
<div class="jhipster-module--property-key">{{ property.key }}</div>
<div class="jhipster-module--property-value" :data-selector="`module-${module.slug}-${property.key}-property-value`">
{{ moduleProperties.get(property.key) }}
<div class="jhipster-module--properties">
<div v-for="property in optionalProperties(module.slug)" class="jhipster-module--property">
<div class="jhipster-module--property-key">{{ property.key }}</div>
<div class="jhipster-module--property-value" :data-selector="`module-${module.slug}-${property.key}-property-value`">
{{ moduleProperties.get(property.key) }}
</div>
</div>
</div>
</div>
</div>

<button
tabindex="3"
class="jhipster-module--apply-button"
:disabled="disabledApplication(module.slug)"
@click="applyModule(module.slug)"
:data-selector="`module-${module.slug}-application-button`"
>
Apply
</button>
<button
tabindex="4"
class="jhipster-module--apply-button"
:disabled="disabledApplication(module.slug)"
@click="applyModule(module.slug)"
:data-selector="`module-${module.slug}-application-button`"
>
Apply
</button>
</div>
</div>
</div>
</div>
Expand Down
20 changes: 19 additions & 1 deletion src/main/webapp/app/module/primary/modules/Modules.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,28 @@
}
.jhipster-modules-list {
flex-grow: 1;
}
.jhipster-modules-list--search {
margin: 15px 0;
padding: 0 15px;
height: 100vh;
height: 70px;
}
.jhipster-modules-list--search-field {
width: 100%;
font-size: 2em;
border: 1px solid #29293b;
border-radius: 20px;
padding: 0 15px;
}
.jhipster-modules-list--categories {
height: calc(100vh - 100px);
overflow-y: auto;
flex-grow: 1;
padding: 0 15px;
}
.jhipster-module {
Expand Down
5 changes: 5 additions & 0 deletions src/test/javascript/spec/module/domain/Modules.fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export const defaultModules = (): Modules => ({
},
],
},
{
slug: 'banner',
description: 'Add a banner to the application',
properties: [],
},
],
},
],
Expand Down
33 changes: 33 additions & 0 deletions src/test/javascript/spec/module/primary/Modules.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,39 @@ describe('Modules', () => {
const [message] = alertBus.error.getCall(0).args;
expect(message).toBe('Module "spring-cucumber" not applied');
});

it('Should filter modules with one matching slug module', async () => {
const modules = repositoryWithModules();
const wrapper = await filledModuleForm(modules);

wrapper.find(wrappedElement('modules-filter-field')).setValue('spring-cucumber');
await flushForm(wrapper);

expect(wrapper.find(wrappedElement('module-banner-application-button')).exists()).toBe(false);
expect(wrapper.find(wrappedElement('module-spring-cucumber-application-button')).exists()).toBe(true);
});

it('Should filter modules with one matching description module', async () => {
const modules = repositoryWithModules();
const wrapper = await filledModuleForm(modules);

wrapper.find(wrappedElement('modules-filter-field')).setValue('Add cucumber');
await flushForm(wrapper);

expect(wrapper.find(wrappedElement('module-banner-application-button')).exists()).toBe(false);
expect(wrapper.find(wrappedElement('module-spring-cucumber-application-button')).exists()).toBe(true);
});

it('Should filter modules with no maching module', async () => {
const modules = repositoryWithModules();
const wrapper = await filledModuleForm(modules);

wrapper.find(wrappedElement('modules-filter-field')).setValue('pouet');
await flushForm(wrapper);

expect(wrapper.find(wrappedElement('module-banner-application-button')).exists()).toBe(false);
expect(wrapper.find(wrappedElement('module-spring-cucumber-application-button')).exists()).toBe(false);
});
});

const componentWithModules = async (): Promise<VueWrapper> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const restModules = (): RestModules => ({
description: 'Add cucumber to the application',
properties: restModuleProperties(),
},
{
slug: 'banner',
description: 'Add a banner to the application',
},
],
},
],
Expand Down

0 comments on commit b6ccdac

Please sign in to comment.