Skip to content
Snippets Groups Projects
Commit 933214dc authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

Remove organization-select

parent 05719454
No related branches found
No related tags found
No related merge requests found
{
"select-organization": {
"loading": "Loading...",
"placeholder": "Please select an organization"
}
}
import {OrganizationSelect} from './organization-select.js';
export {OrganizationSelect};
import $ from 'jquery';
import select2 from 'select2';
import select2CSSPath from 'select2/dist/css/select2.min.css';
import {createInstance} from './i18n.js';
import {css, html} from 'lit';
import * as commonUtils from '@dbp-toolkit/common/utils';
import * as commonStyles from '@dbp-toolkit/common/styles';
import select2LangDe from '@dbp-toolkit/organization-select/src/i18n/de/select2';
import select2LangEn from '@dbp-toolkit/organization-select/src/i18n/en/select2';
import JSONLD from '@dbp-toolkit/common/jsonld';
import {AdapterLitElement} from '@dbp-toolkit/provider/src/adapter-lit-element';
select2(window, $);
export class OrganizationSelect extends AdapterLitElement {
constructor() {
super();
this.auth = {};
this._i18n = createInstance();
this.lang = this._i18n.language;
this.entryPointUrl = '';
this.jsonld = null;
this.organizations = [];
// For some reason using the same ID on the whole page twice breaks select2 (regardless if they are in different custom elements)
this.selectId = 'select-organization-' + commonUtils.makeId(24);
this.cache = {};
this.value = '';
this.context = '';
this._onDocumentClicked = this._onDocumentClicked.bind(this);
}
static get properties() {
return {
...super.properties,
lang: {type: String},
entryPointUrl: {type: String, attribute: 'entry-point-url'},
value: {type: String, reflect: true},
context: {type: String},
auth: {type: Object},
};
}
$(selector) {
return $(this.shadowRoot.querySelector(selector));
}
select2IsInitialized(elm) {
return elm !== null && elm.hasClass('select2-hidden-accessible');
}
connectedCallback() {
super.connectedCallback();
document.addEventListener('click', this._onDocumentClicked);
this.updateSelect2();
}
disconnectedCallback() {
document.removeEventListener('click', this._onDocumentClicked);
super.disconnectedCallback();
}
async load_organizations() {
if (this.cache[this.lang] === undefined) {
this.cache[this.lang] = this.getAssociatedOrganizations();
}
this.organizations = await this.cache[this.lang];
}
_needsLoading() {
return this.cache[this.lang] === undefined;
}
_onDocumentClicked(ev) {
// Close the popup when clicking outside of select2
if (!ev.composedPath().includes(this)) {
const $select = this.$('#' + this.selectId);
if ($select.length && this.select2IsInitialized($select)) {
$select.select2('close');
}
}
}
_clearSelect2() {
const $select = this.$('#' + this.selectId);
console.assert($select.length, 'select2 missing');
// we need to destroy Select2 and remove the event listeners before we can initialize it again
if (this.select2IsInitialized($select)) {
$select.off('select2:select');
$select.empty().trigger('change');
$select.select2('destroy');
}
}
async updateSelect2() {
const i18n = this._i18n;
await this.updateComplete;
const $select = this.$('#' + this.selectId);
console.assert($select.length, 'select2 missing');
// Show an empty select until we load the organizations
if (this._needsLoading()) {
this._clearSelect2();
$select.select2({
width: '100%',
language: this.lang === 'de' ? select2LangDe() : select2LangEn(),
placeholder: i18n.t('select-organization.loading'),
data: [],
disabled: true,
});
}
this.removeAttribute('data-organizations-loaded');
await this.load_organizations();
this.setAttribute('data-organizations-loaded', '');
this._clearSelect2();
const data = this.organizations.map((item) => {
return {id: item.object['@id'], text: item.name};
});
data.sort((a, b) => {
return a.text < b.text ? -1 : a.text > b.text ? 1 : 0;
});
$select
.select2({
width: '100%',
language: this.lang === 'de' ? select2LangDe() : select2LangEn(),
placeholder: i18n.t('select-organization.placeholder'),
dropdownParent: this.$('#select-organization-dropdown'),
data: data,
disabled: false,
})
.on('select2:select', () => {
this.value = $select.select2('data')[0].id;
});
// If none is selected, default to the first one
if (!this.value.length && data.length) {
this.value = data[0].id;
}
// Apply the selection
$select.val(this.value).trigger('change');
}
fireEvent() {
const organization = this.organizations.find((item) => {
return item.object['@id'] === this.value;
});
const $this = $(this);
if (organization === undefined) {
$this.attr('data-object', null);
$this.data('object', null);
return;
}
this.setDataObject(organization);
const event = new CustomEvent('change', {
bubbles: true,
composed: true,
detail: {
value: organization.value,
object: organization.object,
},
});
this.dispatchEvent(event);
}
setDataObject(organization) {
const $this = $(this);
$this.attr('data-object', JSON.stringify(organization.object));
$this.data('object', organization.object);
}
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
case 'lang':
this._i18n.changeLanguage(this.lang);
this.updateSelect2();
break;
case 'value': {
this.updateSelect2();
this.fireEvent();
break;
}
case 'context': {
delete this.cache[this.lang];
this.updateSelect2();
break;
}
case 'entryPointUrl':
JSONLD.getInstance(this.entryPointUrl).then(
(jsonld) => {
this.jsonld = jsonld;
},
{},
this.lang
);
break;
case 'auth':
this.initAuthPersonOnce().then();
break;
default:
}
});
super.update(changedProperties);
}
async initAuthPersonOnce() {
if (!this.auth.person || this.hasAttribute('data-auth-person-init-finished')) {
return;
}
this.cache = {};
await this.updateSelect2();
// this attribute is used in end2end tests
this.setAttribute('data-auth-person-init-finished', '');
}
/**
* Returns the list of assigned libraries of the current user
*
* @returns {Array} list of organization objects
*/
async getAssociatedOrganizations() {
if (!this.auth.person) {
return [];
}
let orgUrl =
this.entryPointUrl +
'/base/people/' +
encodeURIComponent(this.auth['person-id']) +
'/organizations' +
'?context=' +
encodeURIComponent(this.context) +
'&lang=' +
encodeURIComponent(this.lang);
let response = await fetch(orgUrl, {
headers: {
'Content-Type': 'application/ld+json',
Authorization: 'Bearer ' + this.auth.token,
},
});
if (!response.ok) throw new Error(response.statusText);
let data = await response.json();
let results = [];
for (let org of data['hydra:member']) {
let organization = {
id: org.identifier,
name: org.name,
url: org.url,
value: org['@id'],
object: org,
};
results.push(organization);
if (organization.value === this.value) {
this.setDataObject(organization);
}
}
return results;
}
static get styles() {
// language=css
return css`
${commonStyles.getThemeCSS()}
${commonStyles.getGeneralCSS()}
${commonStyles.getNotificationCSS()}
${commonStyles.getSelect2CSS()}
`;
}
render() {
const select2CSS = commonUtils.getAssetURL(select2CSSPath);
return html`
<link rel="stylesheet" href="${select2CSS}" />
<div class="select">
<div class="select2-control control">
<!-- https://select2.org-->
<select
id="${this.selectId}"
name="select-organization"
class="select"
style="visibility: hidden;"></select>
</div>
<div id="select-organization-dropdown"></div>
</div>
`;
}
}
import {assert} from '@esm-bundle/chai';
import '../src/dbp-organization-select.js';
import '../src/demo.js';
suite('dbp-organization-select basics', () => {
let node;
setup(async () => {
node = document.createElement('dbp-organization-select');
document.body.appendChild(node);
await node.updateComplete;
});
teardown(() => {
node.remove();
});
test('should render', () => {
assert.isNotNull(node.shadowRoot);
});
});
suite('dbp-organization-select-demo basics', () => {
let node;
setup(async () => {
node = document.createElement('dbp-organization-select-demo');
document.body.appendChild(node);
await node.updateComplete;
});
teardown(() => {
node.remove();
});
test('should render', () => {
assert.isNotNull(node.shadowRoot);
});
});
......@@ -1878,7 +1878,7 @@
resolved "https://registry.yarnpkg.com/@open-wc/dedupe-mixin/-/dedupe-mixin-1.3.0.tgz#0df5d438285fc3482838786ee81895318f0ff778"
integrity sha512-UfdK1MPnR6T7f3svzzYBfu3qBkkZ/KsPhcpc3JYhsUY4hbpwNF9wEQtD4Z+/mRqMTJrKg++YSxIxE0FBhY3RIw==
"@open-wc/scoped-elements@^2.0.0", "@open-wc/scoped-elements@^2.1.0":
"@open-wc/scoped-elements@^2.1.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@open-wc/scoped-elements/-/scoped-elements-2.1.1.tgz#a43a2167d259af1f113301fcc93b1b9a6c371991"
integrity sha512-qQAtVIK2H1oUIM2oSrCBnf1+ZGHd2nIowt1tete+Dn9rNXIogAMJlUBY/R1NR9MuuJvQ1MeFjgQoDmb05TUdkw==
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment