fix: make action chips react to changes of their item

This commit is contained in:
Thea Schöbl
2022-01-25 09:08:02 +00:00
parent b5f239ea4e
commit c0d0b1bd99
4 changed files with 37 additions and 28 deletions

View File

@@ -24,19 +24,29 @@ import {SCDateSeries, SCThings, SCThingType} from '@openstapps/core';
styleUrls: ['action-chip-list.scss'],
})
export class ActionChipListComponent {
private _item: SCThings;
/**
* If chips are applicable
*/
applicable: Record<string, () => boolean> = {
locate: () => this.item.hasOwnProperty('inPlace'),
event: () =>
this.item.type === SCThingType.AcademicEvent ||
(this.item.type === SCThingType.DateSeries &&
(this.item as SCDateSeries).dates.length > 0),
};
applicable: Record<string, boolean> = {};
/**
* The item the action belongs to
*/
@Input() item: SCThings;
@Input() set item(item: SCThings) {
this._item = item;
this.applicable = {
locate: this.item.hasOwnProperty('inPlace'),
event:
item.type === SCThingType.AcademicEvent ||
(item.type === SCThingType.DateSeries &&
(item as SCDateSeries).dates.length > 0),
};
}
get item() {
return this._item;
}
}

View File

@@ -1,11 +1,11 @@
<div>
<stapps-locate-action-chip
*ngIf="applicable['locate']()"
*ngIf="applicable.locate"
[item]="item"
></stapps-locate-action-chip>
<!-- Add Event Chip needs to load data and should be the last -->
<stapps-add-event-action-chip
*ngIf="applicable['event']()"
*ngIf="applicable.event"
[item]="item"
></stapps-add-event-action-chip>
</div>

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
import {Component, Input, OnDestroy} from '@angular/core';
import {PopoverController} from '@ionic/angular';
import {SCDateSeries, SCThing, SCThingType, SCUuid} from '@openstapps/core';
import {difference, map} from 'lodash-es';
@@ -42,7 +42,7 @@ enum AddEventStates {
styleUrls: ['add-event-action-chip.scss'],
animations: [chipSkeletonTransition, chipTransition],
})
export class AddEventActionChipComponent implements OnInit, OnDestroy {
export class AddEventActionChipComponent implements OnDestroy {
/**
* Associated date series
*/
@@ -58,11 +58,6 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
*/
icon: string;
/**
* Item
*/
@Input() item: SCThing;
/**
* Label
*/
@@ -136,10 +131,18 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
/**
* Init
*/
ngOnInit() {
@Input() set item(item: SCThing) {
// Angular optimizes and reuses components, so in lists, sometimes the same
// component is used for different items. This means that the component
// suddenly changes to a different item. This is a problem because the
// component is not aware of the new item if we just used ngOnInit.
if (this.uuidSubscription) {
this.uuidSubscription.unsubscribe();
}
this.associatedDateSeries =
this.item.type === SCThingType.DateSeries
? Promise.resolve([this.item as SCDateSeries])
item.type === SCThingType.DateSeries
? Promise.resolve([item as SCDateSeries])
: this.dataProvider
.coordinatedSearch({
filter: {
@@ -155,7 +158,7 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
{
arguments: {
field: 'event.uid',
value: this.item.uid,
value: item.uid,
},
type: 'value',
},

View File

@@ -55,11 +55,6 @@ export class CoordinatedSearchProvider {
*/
queue: OngoingQuery[] = [];
/**
* Default latency of search requests
*/
latencyMs = 50;
/**
* Start a coordinated search that merges requests across components
*
@@ -69,19 +64,20 @@ export class CoordinatedSearchProvider {
*/
async coordinatedSearch(
query: SCSearchRequest,
latencyMs?: number,
latencyMs = 50,
): Promise<SCSearchResponse> {
const ongoingQuery: OngoingQuery = {request: query};
this.queue.push(ongoingQuery);
if (this.queue.length < this.dataProvider.backendQueriesLimit) {
await delay(latencyMs ?? this.latencyMs);
await delay(latencyMs);
}
if (this.queue.length > 0) {
// because we are guaranteed to have limited our queue size to be
// <= to the backendQueriesLimite as of above, we can bypass the wrapper
// in the data provider that usually would be responsible for splitting up the requests
const responses = this.dataProvider.client.multiSearch(
arrayToIndexMap(this.queue.map(it => it.request)),
);