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'], styleUrls: ['action-chip-list.scss'],
}) })
export class ActionChipListComponent { export class ActionChipListComponent {
private _item: SCThings;
/** /**
* If chips are applicable * If chips are applicable
*/ */
applicable: Record<string, () => boolean> = { 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),
};
/** /**
* The item the action belongs to * 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> <div>
<stapps-locate-action-chip <stapps-locate-action-chip
*ngIf="applicable['locate']()" *ngIf="applicable.locate"
[item]="item" [item]="item"
></stapps-locate-action-chip> ></stapps-locate-action-chip>
<!-- Add Event Chip needs to load data and should be the last --> <!-- Add Event Chip needs to load data and should be the last -->
<stapps-add-event-action-chip <stapps-add-event-action-chip
*ngIf="applicable['event']()" *ngIf="applicable.event"
[item]="item" [item]="item"
></stapps-add-event-action-chip> ></stapps-add-event-action-chip>
</div> </div>

View File

@@ -13,7 +13,7 @@
* You should have received a copy of the GNU General Public License along with * You should have received a copy of the GNU General Public License along with
* this program. If not, see <https://www.gnu.org/licenses/>. * 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 {PopoverController} from '@ionic/angular';
import {SCDateSeries, SCThing, SCThingType, SCUuid} from '@openstapps/core'; import {SCDateSeries, SCThing, SCThingType, SCUuid} from '@openstapps/core';
import {difference, map} from 'lodash-es'; import {difference, map} from 'lodash-es';
@@ -42,7 +42,7 @@ enum AddEventStates {
styleUrls: ['add-event-action-chip.scss'], styleUrls: ['add-event-action-chip.scss'],
animations: [chipSkeletonTransition, chipTransition], animations: [chipSkeletonTransition, chipTransition],
}) })
export class AddEventActionChipComponent implements OnInit, OnDestroy { export class AddEventActionChipComponent implements OnDestroy {
/** /**
* Associated date series * Associated date series
*/ */
@@ -58,11 +58,6 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
*/ */
icon: string; icon: string;
/**
* Item
*/
@Input() item: SCThing;
/** /**
* Label * Label
*/ */
@@ -136,10 +131,18 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
/** /**
* Init * 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.associatedDateSeries =
this.item.type === SCThingType.DateSeries item.type === SCThingType.DateSeries
? Promise.resolve([this.item as SCDateSeries]) ? Promise.resolve([item as SCDateSeries])
: this.dataProvider : this.dataProvider
.coordinatedSearch({ .coordinatedSearch({
filter: { filter: {
@@ -155,7 +158,7 @@ export class AddEventActionChipComponent implements OnInit, OnDestroy {
{ {
arguments: { arguments: {
field: 'event.uid', field: 'event.uid',
value: this.item.uid, value: item.uid,
}, },
type: 'value', type: 'value',
}, },

View File

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