Skip to content

Commit

Permalink
- Collections, Items, Processes, SearchableList: Add new prop…
Browse files Browse the repository at this point in the history
…erty `loadAdditionalData` to load additional data in expanded state.

- `SearchableList`: `detailsToggled` is not emitted to parent any longer, the parent components do this now directly.
  • Loading branch information
m-mohr committed Jul 9, 2021
1 parent ff306a7 commit bcb9837
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 41 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `ModelBuilder` component to nicely visualize process graphs (migrated over from Web Editor)
- `Processes`: Make `showGraph` prop from `Process` component available
- `Collections`, `Items`, `Processes`, `SearchableList`: Add new property `loadAdditionalData` to load additional data in expanded state.

### Changed

- `Logs`: Don't allow passing `null` (to show a loading state) any longer, which was an undocumented left-over from the Web Editor.
- `Process`: Use `ModelBuilder` instead of `ObjectTree` to visualize the processing instructions.
- `Tab` / `Tabs`: Load FontAwesome automatically if not available (Vue environments only).
- CSS styles are processed with SCSS and thus `base.scss` has been renamed to `base.scss`
- `SearchableList`: `detailsToggled` is not emitted to parent any longer, the parent components do this now directly.

### Fixed

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ Shows an (expandable) list of all STAC-based collections available at a back-end
- `offerDetails` / `odder-details` (string): See the corresponding prop in [`SearchableList`](#searchablelist).
- `collapsed` (boolean|null): See the corresponding prop in [`SearchableList`](#searchablelist).
- `heading` (string|null): Specifies the title of the component. If set to `null`, the title is hidden. Defaults to `Collections`.
- `loadAdditionalData` / `load-additional-data` (function|null): See the corresponding prop in [`SearchableList`](#searchablelist).

**Slots:**

Expand Down Expand Up @@ -344,6 +345,7 @@ Shows an (expandable) list of STAC-based Items.
- `offerDetails` / `odder-details` (string): See the corresponding prop in [`SearchableList`](#searchablelist).
- `collapsed` (boolean|null): See the corresponding prop in [`SearchableList`](#searchablelist).
- `heading` (string|null): Specifies the title of the component. If set to `null`, the title is hidden. Defaults to `Items`.
- `loadAdditionalData` / `load-additional-data` (function|null): See the corresponding prop in [`SearchableList`](#searchablelist).

**Slots:**

Expand Down Expand Up @@ -525,6 +527,7 @@ Shows an (expandable) list of all processes available at a back-end.
- `collapsed` (boolean|null): See the corresponding prop in [`SearchableList`](#searchablelist).
- `heading` (string|null): Specifies the title of the component. If set to `null`, the title is hidden. Defaults to `Processes`.
- `showGraph` / `show-graph` (boolean): See the corresponding prop in [`Process`](#process).
- `loadAdditionalData` / `load-additional-data` (function|null): See the corresponding prop in [`SearchableList`](#searchablelist).

**Slots:**

Expand Down Expand Up @@ -556,6 +559,10 @@ A template to implement searchable, sortable and collapsible lists (all optional
- `showSummaryOnExpand` / `show-summary-on-expand` (boolean): If set to `false`, the summary gets hidden for expanded elements. Defaults to `true`.
- `heading` (string|null): Specifies the title of the component. If set to `null`, the title is hidden. Defaults to `null`.
- `searchMinLength` / `search-min-length` (integer): The number of characters required to be given until the search starts. Defaults to `2` as it's usually not very meaningful to search for a single character.
- `loadAdditionalData` / `load-additional-data` (function|null): An asynchronous function that returns newly loaded data and replaces the original data in the viewer. The function has three parameters:
- `key` (integer): Gives the index (for arrays) or the key (for objects) of the toggled element in the array or object given in the prop `data`.
- `identifier` (number|string): Gives the identifier of the toggled element (corresponds to the values selected via the prop `identifierKey`).
- `data` (object): The original data.

**Slots:**

Expand Down
11 changes: 10 additions & 1 deletion components/Collections.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component collections">
<SearchableList :data="collections" identifierKey="id" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed">
<SearchableList :data="collections" identifierKey="id" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" :loadAdditionalData="loadAdditionalData" @detailsToggled="detailsToggled">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #summary="scope"><slot name="summary" v-bind="scope" /></template>
<template #details="slot">
Expand Down Expand Up @@ -53,10 +53,19 @@ export default {
collapsed: {
type: Boolean,
default: null
},
loadAdditionalData: {
type: Function,
default: null
}
},
beforeCreate() {
Utils.enableHtmlProps(this);
},
methods: {
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
</script>
Expand Down
7 changes: 6 additions & 1 deletion components/FileFormats.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component file-formats">
<SearchableList :data="fileFormats" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed">
<SearchableList :data="fileFormats" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" @detailsToggled="detailsToggled">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #summary="slot">
<slot name="summary" v-bind="slot">
Expand Down Expand Up @@ -97,6 +97,11 @@ export default {
},
beforeCreate() {
Utils.enableHtmlProps(this);
},
methods: {
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
</script>
Expand Down
9 changes: 8 additions & 1 deletion components/Items.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component items">
<SearchableList :data="data" identifierKey="id" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" @summaries="updateFeatures" ref="list">
<SearchableList :data="data" identifierKey="id" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" :loadAdditionalData="loadAdditionalData" @summaries="updateFeatures" @detailsToggled="detailsToggled" ref="list">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #after-search-box>
<slot v-if="showMap" name="map" :geojson="geojson" :mapOptions="mapOptions">
Expand Down Expand Up @@ -64,6 +64,10 @@ export default {
collapsed: {
type: Boolean,
default: null
},
loadAdditionalData: {
type: Function,
default: null
}
},
data() {
Expand Down Expand Up @@ -144,6 +148,9 @@ export default {
geom.addTo(this.map.instance);
}
this.map.geometries = geom;
},
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion components/Processes.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component processes">
<SearchableList :data="processes" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed">
<SearchableList :data="processes" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" :loadAdditionalData="loadAdditionalData" @detailsToggled="detailsToggled">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #summary="scope"><slot name="summary" v-bind="scope" /></template>
<template #details="slot">
Expand Down Expand Up @@ -56,10 +56,19 @@ export default {
showGraph: {
type: Boolean,
default: false
},
loadAdditionalData: {
type: Function,
default: null
}
},
beforeCreate() {
Utils.enableHtmlProps(this);
},
methods: {
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
</script>
Expand Down
90 changes: 55 additions & 35 deletions components/SearchableList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
<ul v-else class="list" :class="{expandable: offerDetails}">
<li v-for="(summary, i) in summaries" :key="summary.identifier" v-show="summary.show" :class="{expanded: showDetails[i]}">
<summary @click="toggleDetails(i)" class="summary" :class="{experimental: summary.experimental, deprecated: summary.deprecated}">
<slot name="summary" :summary="summary" :item="data[summary.index]">
<slot name="summary" :summary="summary" :item="summary.data">
<strong>{{ summary.identifier }}</strong>
<small v-if="summary.summary" :class="{hideOnExpand: !showSummaryOnExpand}">{{ summary.summary }}</small>
</slot>
</summary>
<div class="details" v-if="typeof showDetails[i] === 'boolean'" v-show="showDetails[i] === true">
<slot name="details" :summary="summary" :item="data[summary.index]">
<Loading v-if="!summary.loaded" />
<slot v-else name="details" :summary="summary" :item="summary.data">
No details available!
</slot>
</div>
Expand All @@ -37,11 +38,13 @@

<script>
import Utils from '../utils';
import Loading from './internal/Loading.vue';
import Vue from 'vue';
export default {
name: 'SearchableList',
components: {
Loading,
SearchBox: () => import('./SearchBox.vue')
},
props: {
Expand Down Expand Up @@ -85,9 +88,13 @@ export default {
type: Boolean,
default: null
},
searchMinLength:{
searchMinLength: {
type: Number,
default: 2
},
loadAdditionalData: {
type: Function,
default: null
}
},
data() {
Expand All @@ -104,6 +111,11 @@ export default {
};
},
watch: {
loadAdditionalData: {
handler() {
this.generateSummaries(this.summaries);
}
},
data: {
immediate: true,
handler(data, oldData) {
Expand All @@ -113,34 +125,7 @@ export default {
if (data === oldData) {
return;
}
let summaries = [];
for(let index in this.data) {
let entry = this.data[index];
let summary = {
identifier: index,
summary: '',
show: true,
index: index,
experimental: entry.experimental,
deprecated: entry.deprecated
};
if (typeof entry[this.identifierKey] === 'string') {
summary.identifier = entry[this.identifierKey];
}
if (typeof entry[this.summaryKey] === 'string') {
summary.summary = entry[this.summaryKey];
}
summaries.push(Vue.observable(summary));
}
if (this.sort) {
if (Utils.isObject(this.data)) {
summaries = Object.values(summaries);
}
summaries.sort((a,b) => Utils.compareStringCaseInsensitive(a.identifier, b.identifier));
}
this.summaries = summaries;
this.generateSummaries(data);
}
},
externalSearchTerm: {
Expand Down Expand Up @@ -193,6 +178,36 @@ export default {
}
},
methods: {
generateSummaries() {
let hasLoader = typeof this.loadAdditionalData === 'function';
let summaries = [];
for(let index in this.data) {
let entry = this.data[index];
let summary = {
identifier: index,
summary: '',
show: true,
loaded: !hasLoader,
index: index,
experimental: entry.experimental,
deprecated: entry.deprecated,
data: entry
};
if (typeof entry[this.identifierKey] === 'string') {
summary.identifier = entry[this.identifierKey];
}
if (typeof entry[this.summaryKey] === 'string') {
summary.summary = entry[this.summaryKey];
}
summaries.push(Vue.observable(summary));
}
if (this.sort) {
summaries.sort((a,b) => Utils.compareStringCaseInsensitive(a.identifier, b.identifier));
}
this.summaries = summaries;
},
toggleHeading(show = null) {
if (this.collapsed === null) {
return;
Expand All @@ -203,7 +218,7 @@ export default {
this.$parent.$emit('headingToggled', this.showList);
}
},
toggleDetails(i, newState) {
async toggleDetails(i, newState) {
if (!this.offerDetails) {
return;
}
Expand All @@ -215,10 +230,15 @@ export default {
}
this.$set(this.showDetails, i, newState);
let summary = this.summaries[i];
this.$emit('detailsToggled', newState, summary.index, summary.identifier, this.data[summary.index]);
if (this.$parent) {
this.$parent.$emit('detailsToggled', newState, summary.index, summary.identifier, this.data[summary.index]);
if (newState && typeof this.loadAdditionalData === 'function' && !summary.loaded) {
try {
summary.data = await this.loadAdditionalData(summary.index, summary.identifier, summary.data);
summary.loaded = true;
} catch (error) {
console.error(error);
}
}
this.$emit('detailsToggled', newState, summary.index, summary.identifier, summary.data);
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion components/ServiceTypes.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component service-types">
<SearchableList :data="services" summaryKey="title" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed">
<SearchableList :data="services" summaryKey="title" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" @detailsToggled="detailsToggled">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #summary="scope"><slot name="summary" v-bind="scope" /></template>
<template #details="slot">
Expand Down Expand Up @@ -51,6 +51,11 @@ export default {
},
beforeCreate() {
Utils.enableHtmlProps(this);
},
methods: {
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
</script>
Expand Down
7 changes: 6 additions & 1 deletion components/UdfRuntimes.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="vue-component udf-runtimes">
<SearchableList :data="runtimes" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed">
<SearchableList :data="runtimes" summaryKey="title" :showSummaryOnExpand="false" :externalSearchTerm="searchTerm" :sort="sort" :offerDetails="offerDetails" :heading="heading" :collapsed="collapsed" @detailsToggled="detailsToggled">
<template #heading="scope"><slot name="heading" v-bind="scope" /></template>
<template #summary="slot">
<slot name="summary" v-bind="slot">
Expand Down Expand Up @@ -65,6 +65,11 @@ export default {
},
beforeCreate() {
Utils.enableHtmlProps(this);
},
methods: {
detailsToggled(...args) {
this.$emit('detailsToggled', ...args);
}
}
}
</script>
Expand Down

0 comments on commit bcb9837

Please sign in to comment.