Skip to content

Commit

Permalink
Bugfix/127 refactor aoe dropdown naar autocomplete (#130)
Browse files Browse the repository at this point in the history
* #127 refactor dropdown naar autocomplete

* #127 happy github
  • Loading branch information
yannickkuypers authored Oct 11, 2023
1 parent 48e2173 commit c3b6daf
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 159 deletions.
33 changes: 33 additions & 0 deletions cypress/fixtures/actoren.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[{
"id": 12564,
"uri": "https://dev-id.erfgoed.net/actoren/12564",
"self": "https://dev-actoren.onroerenderfgoed.be/actoren/12564",
"type": {
"id": 1,
"naam": "persoon",
"uri": "foaf:Person"
},
"zichtbaarheid": {
"id": 1,
"naam": "privaat"
},
"omschrijving": "Van Humbeeck, Astrid",
"naam": "Van Humbeeck",
"voornaam": "Astrid",
"status": {
"id": 75,
"status": "Actief"
},
"systemfields": {
"created_at": "2020-10-16T14:03:24.911936+02:00",
"created_by": {
"uri": "https://dev-id.erfgoed.net/actoren/12495",
"description": "Toelatingen Beschermd Erfgoed Aanvragen"
},
"updated_at": "2023-05-05T13:12:06.836065+02:00",
"updated_by": {
"uri": "https://dev-id.erfgoed.net/actoren/12564",
"description": "Van Humbeeck, Astrid"
}
}
}]
39 changes: 39 additions & 0 deletions src/__tests__/FilterAOEActor.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import FilterAOEActor from '../components/smart/FilterAOEActor.vue';
import { defineComponent, ref } from 'vue';
import type { IActor } from '@models/actor';

describe('FilterAanduidingsobject', () => {
describe('default', () => {
const TestComponent = defineComponent({
components: { FilterAOEActor },
setup() {
const actorValue = ref<IActor>();
const setValue = (value: IActor) => (actorValue.value = value);
const getSsoToken = async () => 'Bearer ' + 1;
return { actorValue, setValue, getSsoToken };
},
template:
'<filter-AOE-actor api="https://dev-actoren.onroerenderfgoed.be" :get-sso-token="getSsoToken" :value="actorValue" @update:value="setValue"/>',
});

it('fetches wij actoren, filter and assign the chosen filter to the corresponding data value', () => {
cy.intercept('GET', 'https://dev-actoren.onroerenderfgoed.be/**', { fixture: 'actoren.json' }).as('dataGet');

cy.mount(TestComponent).then(({ component }) => {
cy.dataCy('filter-actor').type('Astrid');
cy.wait('@dataGet').then(() => {
cy.dataCy('filter-actor')
.find('.vl-autocomplete__cta')
.first()
.click()
.then(() => {
expect(component.actorValue).to.deep.equal({
title: 'Van Humbeeck, Astrid',
value: 'https://dev-id.erfgoed.net/actoren/12564',
});
});
});
});
});
});
});
65 changes: 33 additions & 32 deletions src/components/smart/FilterAOEActor.vue
Original file line number Diff line number Diff line change
@@ -1,55 +1,56 @@
<template>
<vl-multiselect
<oe-autocomplete
:id="props.id"
data-cy="filter-actor"
placeholder="Actor"
:mod-multiple="false"
:options="actoren"
:preserve-search="true"
:callback-fn="performAutocompleteSearch"
:value="actorValue"
@update:value="updateValue"
:custom-label="customActorLabel"
@keydown.tab="!props.value ? $event.preventDefault() : null"
>
<template #noResult>
<span>Geen actoren gevonden...</span>
</template>
<template #noOptions>
<span>Geen opties beschikbaar</span>
</template>
</vl-multiselect>
></oe-autocomplete>
</template>

<script setup lang="ts">
import { VlMultiselect } from '@govflanders/vl-ui-design-system-vue3';
import { sortBy } from 'lodash';
import { computed, onBeforeMount, ref } from 'vue';
import OeAutocomplete from '../dumb/OeAutocomplete.vue';
import { computed, ref } from 'vue';
import { ActorService } from '@services/actor.service';
import type { IActor } from '@models/actor';
import type { IAutocompleteOption } from '@models/autocomplete';
import type { IFilterActorProps } from '@models/index';
const props = withDefaults(defineProps<IFilterActorProps>(), {
id: '',
api: '',
actoren: undefined,
value: '',
getSsoToken: undefined,
value: undefined,
});
const emit = defineEmits(['update:value']);
const actorService = new ActorService(props.api, props.getSsoToken);
const actoren = ref<IActor[]>([]);
const actorValue = computed(() => {
return actoren.value.length ? actoren.value.find((actor) => actor.uri === props.value) : undefined;
const actor = actoren?.value.find((g) => g.uri === props.value);
const autocompleteOption: IAutocompleteOption = {
title: actor?.omschrijving as string,
value: actor,
};
return autocompleteOption;
});
const updateValue = (value: IActor) => emit('update:value', value);
const actorService = new ActorService(props.api, props.getSsoToken);
const actoren = ref<IActor[]>([]);
const customActorLabel = (option: IActor) => option.omschrijving;
const updateValue = (value: IActor) => emit('update:value', value);
const performAutocompleteSearch = async (searchTerm: string): Promise<IAutocompleteOption[]> => {
try {
actoren.value = await actorService.getAOEActoren(searchTerm);
const autocompleteData: IAutocompleteOption[] = actoren.value.map((actor) => {
return {
title: actor.omschrijving,
value: actor.uri,
};
});
onBeforeMount(async () => {
if (props.actoren) {
actoren.value = sortBy(props.actoren, 'omschrijving');
} else {
const apiActoren = await actorService.getAOEActoren();
actoren.value = sortBy(apiActoren, 'omschrijving');
return autocompleteData;
} catch (error) {
console.error('Error fetching autocomplete data:', error);
return Promise.resolve([]);
}
});
};
</script>
4 changes: 2 additions & 2 deletions src/models/filter-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export interface IFilterGemeenteProps {
}

export interface IFilterActorProps {
id: string;
api: string;
actoren?: IActor[];
getSsoToken: () => Promise<string>;
value?: string;
getSsoToken: () => Promise<string>;
}

export interface IFilterProvincieProps {
Expand Down
7 changes: 5 additions & 2 deletions src/services/actor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ export class ActorService extends HttpService {
this.getSsoToken = getSsoToken;
}

async getAOEActoren(): Promise<IActor[]> {
async getAOEActoren(searchTerm: string): Promise<IActor[]> {
if (this.actoren?.length) {
return this.actoren;
}
const ssoToken = await this.getSsoToken();
return (
await this.get<IActor[]>(`${this.API_URL}/actoren/wij`, { headers: { Authorization: 'Bearer ' + ssoToken } })
await this.get<IActor[]>(`${this.API_URL}/actoren/wij`, {
headers: { Authorization: 'Bearer ' + ssoToken },
params: { omschrijving: `${searchTerm}*` },
})
).data;
}
}
123 changes: 0 additions & 123 deletions src/stories/smart-components/filter-AOE-actor.stories.ts

This file was deleted.

67 changes: 67 additions & 0 deletions src/stories/smart-components/filter-aoe-actor.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import '@/scss/main.scss';
import FilterAOEActor from '../../components/smart/FilterAOEActor.vue';
import type { Meta, StoryObj } from '@storybook/vue3';

// More on how to set up stories at: https://storybook.js.org/docs/vue/writing-stories/introduction
const meta: Meta<typeof FilterAOEActor> = {
title: 'Smart components/Filter Inputs/FilterAOEActor',
component: FilterAOEActor,
parameters: {
docs: {
description: {
component:
'Specific filter input field to enter a "wij" actor - used as subcomponent of the `FilterInput` component.\n\n All autocomplete props can also be used.',
},
story: {
height: '400px',
},
},
},
tags: ['autodocs'],
argTypes: {
value: {
control: 'text',
description: 'Current uri',
table: {
type: { summary: 'string' },
},
},
api: {
control: 'text',
description: 'Api base url',
table: {
type: { summary: 'string' },
},
},
getSsoToken: {
control: 'text',
description: 'function to get the sso Token from the parent',
table: {
type: { summary: 'string' },
},
},
placeholder: {
control: 'text',
description: 'Input placeholder',
table: {
type: { summary: 'string' },
},
},
'update:value': {
description: 'Emits the selected actor',
table: {
type: { summary: 'IActor' },
},
},
},
};

export default meta;
type Story = StoryObj<typeof FilterAOEActor>;

export const Default: Story = {
args: {
api: 'https://dev-actoren.onroerenderfgoed.be',
id: 'my-id',
},
};

0 comments on commit c3b6daf

Please sign in to comment.