Skip to content

Commit

Permalink
Merge pull request #190 from OnroerendErfgoed/develop
Browse files Browse the repository at this point in the history
Release 0.16.0
  • Loading branch information
wouter-adriaens authored Dec 5, 2023
2 parents 65f80cb + ce4bb89 commit fabe394
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 16 deletions.
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,19 @@ yarn storybook
yarn build:watch
```

#### Symlink

A symlink can be created between the library and implementing applications.
#### Yalc - for sharing locally developed packages across your local environment. - https://github.com/wclr/yalc

```sh
yarn link
Yalc publish
```

Afterwards link the package in the desired implementing application.

```sh
yarn link "vue-components"
yalc add @OnroerendErfgoed/[email protected]
yalc update
yarn
```

Whilst running the `build:watch` command, changes in the library will automatically be reflected in linked applications.

### Type-Check, Compile and Minify for Production

```sh
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"main": "./dist/vue-components.umd.js",
"module": "./dist/vue-components.es.js",
"typings": "./dist/src/main.d.ts",
"version": "0.15.0",
"version": "0.16.0",
"exports": {
".": {
"import": "./dist/vue-components.es.js",
Expand Down
151 changes: 151 additions & 0 deletions src/__tests__/OeSelect.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint-disable vue/one-component-per-file */
import { defineComponent, ref } from 'vue';
import OeSelect from '@components/dumb/OeSelect.vue';
import type { ISelectOption } from '@models/select';

describe('Select', () => {
const select = () => cy.dataCy('oe-select');
const dropdown = () => cy.get('.vl-select__list.vl-select__list--dropdown');
const selectItemPlaceholder = () => cy.get('.vl-select__item.vl-select__item--choice.is-placeholder');
const selectedItem = () => cy.get('.vl-select__item.vl-select__item--selectable');
const selectableItems = () => cy.get('.vl-select__item.vl-select__item--choice.vl-select__item--selectable');

describe('default', () => {
const TestComponent = defineComponent({
components: { OeSelect },
setup() {
const modelValue = ref<ISelectOption>();
const options: ISelectOption[] = [
{ label: 'België', value: 'België' },
{ label: 'Frankrijk', value: 'Frankrijk' },
{ label: 'Duitsland - Land in Centraal-Europa.', value: 'Duitsland' },
];
const customLabel = (option: ISelectOption) => option?.label;

return { options, customLabel, modelValue };
},
template: '<OeSelect v-model="modelValue" :custom-label="customLabel" :options="options"/>',
});

it('renders a custom select with placeholder', () => {
cy.mount(TestComponent);
cy.get('.js-vl-select')
.should('exist')
.should('be.visible')
.find('.vl-select__inner > .vl-input-field')
.should('be.visible')
.find('.vl-select__item.item--placeholder')
.invoke('text')
.should('equal', 'Selecteer een optie');
});

it('does not show the dropdown', () => {
cy.mount(TestComponent);
dropdown().should('not.exist');
});

it('shows the dropdown when clicking at the select element', () => {
cy.mount(TestComponent);
select().click();
dropdown().should('exist');
});

it('renders the placeholder as first element', () => {
cy.mount(TestComponent);
select().click();
selectItemPlaceholder().invoke('text').should('equal', 'Selecteer een optie');
});

it('renders all options with custom label', () => {
cy.mount(TestComponent).then(({ component }) => {
select().click();
selectableItems().each((option, i) => {
expect(option.text()).to.equal(component.options[i].label);
});
});
});

it('updates the model value and closes the dropdown when item is selected', () => {
cy.mount(TestComponent).then(({ component }) => {
select().click();
selectableItems()
.first()
.click()
.then(() => {
selectedItem().invoke('text').should('equal', component.options[0].label);
expect(component.modelValue).to.deep.equal(component.options[0]);
dropdown().should('not.exist');
});
});
});

it('highlights the selected item', () => {
cy.mount(TestComponent);
select().click();
selectableItems()
.first()
.click()
.then(() => {
select().click();
selectableItems().first().should('have.class', 'is-highlighted');
selectableItems().last().should('not.have.class', 'is-highlighted');
});
});
});

describe('custom placeholder', () => {
const TestComponent = defineComponent({
components: { OeSelect },
template: '<OeSelect placeholder="My custom placeholder"/>',
});

it('renders a select with custom placeholder', () => {
cy.mount(TestComponent);
cy.get('.js-vl-select')
.should('exist')
.should('be.visible')
.find('.vl-select__inner > .vl-input-field')
.should('be.visible')
.find('.vl-select__item.item--placeholder')
.invoke('text')
.should('equal', 'My custom placeholder');
});

it('renders the custom placeholder as first element', () => {
cy.mount(TestComponent);
select().click();
selectItemPlaceholder().invoke('text').should('equal', 'My custom placeholder');
});
});

describe('selected value', () => {
const TestComponent = defineComponent({
components: { OeSelect },
setup() {
const modelValue = ref<ISelectOption>({ label: 'België', value: 'België' });
const options: ISelectOption[] = [
{ label: 'België', value: 'België' },
{ label: 'Frankrijk', value: 'Frankrijk' },
{ label: 'Duitsland - Land in Centraal-Europa.', value: 'Duitsland' },
];
const customLabel = (option: ISelectOption) => option?.label;

return { options, customLabel, modelValue };
},
template: '<OeSelect v-model="modelValue" :custom-label="customLabel" :options="options"/>',
});

it('selects the initial boundend value', () => {
cy.mount(TestComponent).then(({ component }) => {
selectedItem().invoke('text').should('equal', component.modelValue.label);
});
});

it('updates the value after modelValue changed', () => {
cy.mount(TestComponent).then(({ component }) => {
component.modelValue = component.options[1];
selectedItem().invoke('text').should('equal', component.options[1].label);
});
});
});
});
16 changes: 13 additions & 3 deletions src/components/dumb/OeSelect.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div
v-click-outside="hideResults"
data-cy="oe-select"
class="js-vl-select"
role="listbox"
data-type="select-one"
Expand Down Expand Up @@ -43,7 +44,7 @@
</template>
<script lang="ts" setup>
import { isEqual } from 'lodash';
import { ref } from 'vue';
import { ref, watch } from 'vue';
import { vClickOutside } from '@directives/click-outside.directive';
import type { ISelectProps } from '@models/select';
Expand All @@ -60,8 +61,8 @@ const props = withDefaults(defineProps<ISelectProps<any>>(), {
const emit = defineEmits(['update:modelValue']);
const options = props.options || [];
const selectedOption = ref(options.find((option) => isEqual(option, props.modelValue)));
const selectOptionLabel = ref<string>(props.customLabel(selectedOption?.value) as string);
const selectedOption = ref(null);
const selectOptionLabel = ref('');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const selectOption = (option: any) => {
Expand All @@ -71,6 +72,15 @@ const selectOption = (option: any) => {
};
const hideResults = () => (showResults.value = false);
watch(
() => props.modelValue,
() => {
selectedOption.value = options.find((option) => isEqual(option, props.modelValue));
selectOptionLabel.value = props.customLabel(selectedOption.value) as string;
},
{ immediate: true }
);
</script>

<style lang="scss" scoped>
Expand Down
2 changes: 1 addition & 1 deletion src/components/smart/OeActorWidgetGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const refresh = () => {
const rowCount = ref(0);
const getColumnDefinitions = (): ColDef[] => {
return [
{ headerName: '#', field: 'id', sort: 'desc', width: 50 },
{ headerName: '#', field: 'id', width: 50 },
{ headerName: 'Naam', field: 'naam', flex: 1 },
{ headerName: 'Voornaam', field: 'voornaam', flex: 1 },
{ headerName: 'Type', field: 'type.naam', colId: 'type', flex: 1 },
Expand Down
4 changes: 2 additions & 2 deletions src/models/header.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface IHeaderProps {
user: IUser;
user: IHeaderUser;
appName: string;
appUrl: string;
profileUrl?: string;
Expand All @@ -10,7 +10,7 @@ export interface IHeaderProps {
showLogoutShortcut?: boolean;
}

export interface IUser {
export interface IHeaderUser {
name?: string;
role?: string;
}
1 change: 1 addition & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export * from './oe-zoneerder-config';
export * from './status';
export * from './system-fields';
export * from './toast';
export * from './user';
export * from './wizard';
2 changes: 1 addition & 1 deletion src/models/select.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export interface ISelectProps<T> {
modelValue: T;
options: T[];
placeholder: string;
placeholder?: string;
customLabel: (option: T) => T;
}

Expand Down
76 changes: 76 additions & 0 deletions src/models/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
export class User {
public actor: IUserActor;
public groups: string[];
public organisatie: IOrganisatie;
public personid: string;
public persoonsgegevens: IPersoonsgegevens;
public ssoToken: string;
public userid: string;

constructor(user: IUser) {
this.actor = user.actor;
this.groups = user.groups;
this.organisatie = user.organisatie;
this.personid = user.personid;
this.persoonsgegevens = user.persoonsgegevens;
this.ssoToken = user.sso_token;
this.userid = user.userid;
}

public hasRole(role: string): boolean {
return !!this.groups?.find((group) => group === role);
}
}

/* User object */
export interface IUser {
actor: IUserActor;
groups: string[];
organisatie: IOrganisatie;
personid: string;
persoonsgegevens: IPersoonsgegevens;
sso_token: string;
userid: string;
}

interface IUserActor {
erkenningen: IErkenning[];
id: number;
instantie_actor_omschrijving: string;
instantie_actor_uri: string;
omschrijving: string;
uid: string;
uri: string;
}

interface IErkenning {
erkend_als: string;
erkend_voor: string;
erkenningsnummer: string;
geldigheid: string;
id: number;
omschrijving: string;
reden_erkenning: IRedenErkenning;
type: string;
type_erkenning_id: number;
uri: string;
}

interface IRedenErkenning {
id: number;
reden_erkenning: string;
}

interface IOrganisatie {
id: string;
naam: string;
type: string;
}

interface IPersoonsgegevens {
email: string;
naam: string;
omschrijving: string;
rijksregisternummer: string;
voornaam: string;
}

0 comments on commit fabe394

Please sign in to comment.