Skip to content

Commit d998716

Browse files
committed
Merge branch 'beta' into alpha
2 parents 8e0bb51 + b25ca82 commit d998716

File tree

10 files changed

+507
-50
lines changed

10 files changed

+507
-50
lines changed

CHANGELOG.md

Lines changed: 269 additions & 1 deletion
Large diffs are not rendered by default.

CHANGELOG/CHANGELOG_beta.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
# [2.2.0-beta.16](https://github.com/ReliefApplications/ems-frontend/compare/v2.2.0-beta.15...v2.2.0-beta.16) (2023-12-08)
2+
3+
4+
### Bug Fixes
5+
6+
* prevent aggregation fields to be fetched before query builder is ready ([#2139](https://github.com/ReliefApplications/ems-frontend/issues/2139)) ([3bee583](https://github.com/ReliefApplications/ems-frontend/commit/3bee5837c221a799d9e479e91cab0131afb3c259))
7+
* toggle of archived records would create incorrect list ([#2132](https://github.com/ReliefApplications/ems-frontend/issues/2132)) ([f1abf81](https://github.com/ReliefApplications/ems-frontend/commit/f1abf811189f67841a8770ac5e6cc35af0bf745c))
8+
9+
10+
### Features
11+
12+
* add filter input & output in app-widget ([4d94cef](https://github.com/ReliefApplications/ems-frontend/commit/4d94cefd8718f0b382679e2d0fc79e6242bb49e7))
13+
* allow fields from ref data linked to a resource to be used ([#1575](https://github.com/ReliefApplications/ems-frontend/issues/1575)) ([cb8b30c](https://github.com/ReliefApplications/ems-frontend/commit/cb8b30ca36074c1544bf3d95796a6553f1de1b55))
14+
15+
# [2.2.0-beta.15](https://github.com/ReliefApplications/ems-frontend/compare/v2.2.0-beta.14...v2.2.0-beta.15) (2023-12-07)
16+
17+
18+
### Bug Fixes
19+
20+
* editing widgets could sometimes scroll to top of dashboard ([#2135](https://github.com/ReliefApplications/ems-frontend/issues/2135)) ([da6dd93](https://github.com/ReliefApplications/ems-frontend/commit/da6dd93460ada1446233159ed5988484bd2f9530))
21+
* few issues with templating & reference data ([c504e92](https://github.com/ReliefApplications/ems-frontend/commit/c504e922e1f73a6f8030b1388f066b6853a0dd4c))
22+
* incorrectly sized columns ([#2127](https://github.com/ReliefApplications/ems-frontend/issues/2127)) ([c0be7b1](https://github.com/ReliefApplications/ems-frontend/commit/c0be7b1e30ac4b71f659b97845caf2f79adf8edd))
23+
* pull jobs would not be editable ([cc9d685](https://github.com/ReliefApplications/ems-frontend/commit/cc9d685c3620450a38bd3f0cbbaf38d697dcac6d))
24+
* remove code information in url after login ([bcfb603](https://github.com/ReliefApplications/ems-frontend/commit/bcfb603b2a74a03437ae6a236451de22c343ca3d))
25+
* text widget edition would lose widget display configuration ([7f3b18b](https://github.com/ReliefApplications/ems-frontend/commit/7f3b18ba98fded73b0a90681a6019fbc86504707))
26+
127
# [2.2.0-beta.14](https://github.com/ReliefApplications/ems-frontend/compare/v2.2.0-beta.13...v2.2.0-beta.14) (2023-12-05)
228

329

apps/back-office/src/app/dashboard/pages/form-records/form-records.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ <h1 class="!m-0">
159159
</div>
160160
</div>
161161
<ui-paginator
162-
[disabled]="loadingMore"
162+
[disabled]="loadingMore || updating"
163163
[pageSize]="pageInfo.pageSize"
164164
[pageIndex]="pageInfo.pageIndex"
165165
[totalItems]="pageInfo.length"

apps/back-office/src/app/dashboard/pages/form-records/form-records.component.ts

Lines changed: 93 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ import {
2727
SnackbarService,
2828
UIPageChangeEvent,
2929
UILayoutService,
30+
handleTablePageEvent,
3031
} from '@oort-front/ui';
3132
import { GraphQLError } from 'graphql';
33+
import {
34+
getCachedValues,
35+
updateQueryUniqueValues,
36+
} from '../../../utils/update-queries';
37+
import { ApolloQueryResult } from '@apollo/client';
3238

3339
/** Default items per query, for pagination */
3440
const ITEMS_PER_PAGE = 10;
@@ -60,6 +66,8 @@ export class FormRecordsComponent
6066
private historyId = '';
6167
public cachedRecords: Record[] = [];
6268
public defaultColumns = DEFAULT_COLUMNS;
69+
/** Updating status */
70+
public updating = false;
6371

6472
// === DELETED RECORDS VIEW ===
6573
public showDeletedRecords = false;
@@ -68,7 +76,7 @@ export class FormRecordsComponent
6876
pageIndex: 0,
6977
pageSize: ITEMS_PER_PAGE,
7078
length: 0,
71-
endCursor: null as string | null,
79+
endCursor: '',
7280
};
7381

7482
/** @returns True if the layouts tab is empty */
@@ -126,6 +134,7 @@ export class FormRecordsComponent
126134
variables: {
127135
id: this.id,
128136
first: ITEMS_PER_PAGE,
137+
afterCursor: this.pageInfo.endCursor,
129138
display: false,
130139
showDeletedRecords: this.showDeletedRecords,
131140
},
@@ -134,21 +143,7 @@ export class FormRecordsComponent
134143
this.recordsQuery.valueChanges
135144
.pipe(takeUntil(this.destroy$))
136145
.subscribe(({ errors, data, loading }) => {
137-
this.cachedRecords.push(
138-
...data.form.records.edges.map((x: any) => x.node)
139-
);
140-
this.dataSource = this.cachedRecords.slice(
141-
ITEMS_PER_PAGE * this.pageInfo.pageIndex,
142-
ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1)
143-
);
144-
this.pageInfo.length = data.form.records.totalCount;
145-
this.pageInfo.endCursor = data.form.records.pageInfo.endCursor;
146-
this.loadingMore = false;
147-
148-
this.form = data.form;
149-
this.breadcrumbService.setBreadcrumb('@form', this.form.name as string);
150-
this.setDisplayedColumns();
151-
this.loading = loading;
146+
this.updateValues(data, loading, true);
152147

153148
if (errors) {
154149
// TO-DO: Check why it's not working as intended.
@@ -163,29 +158,93 @@ export class FormRecordsComponent
163158
});
164159
}
165160

161+
/**
162+
* Update Records datas query.
163+
*
164+
* @param refetch erase previous query results
165+
*/
166+
private fetchRecordsData(refetch?: boolean): void {
167+
this.loading = true;
168+
this.updating = true;
169+
const variables = {
170+
id: this.id,
171+
first: ITEMS_PER_PAGE,
172+
afterCursor: refetch ? null : this.pageInfo.endCursor,
173+
display: false,
174+
showDeletedRecords: this.showDeletedRecords,
175+
};
176+
// get the records linked to the form
177+
const cachedValues: FormRecordsQueryResponse = getCachedValues(
178+
this.apollo.client,
179+
GET_FORM_RECORDS,
180+
variables
181+
);
182+
if (refetch) {
183+
this.cachedRecords = [];
184+
this.pageInfo.pageIndex = 0;
185+
}
186+
if (cachedValues) {
187+
this.updateValues(cachedValues, false, refetch);
188+
} else {
189+
if (refetch) {
190+
this.recordsQuery.refetch(variables);
191+
} else {
192+
this.recordsQuery
193+
.fetchMore({ variables })
194+
.then((results: ApolloQueryResult<FormRecordsQueryResponse>) => {
195+
this.updateValues(results.data, results.loading);
196+
});
197+
}
198+
}
199+
}
200+
201+
/**
202+
* Update records data value
203+
*
204+
* @param data query response data
205+
* @param loading loading status
206+
* @param setForm control if form should be set
207+
*/
208+
private updateValues(
209+
data: FormRecordsQueryResponse,
210+
loading: boolean,
211+
setForm?: boolean
212+
) {
213+
const mappedValues = data.form.records.edges.map((x) => x.node);
214+
this.cachedRecords = updateQueryUniqueValues(
215+
this.cachedRecords,
216+
mappedValues
217+
);
218+
this.pageInfo.length = data.form.records.totalCount;
219+
this.pageInfo.endCursor = data.form.records.pageInfo.endCursor;
220+
this.dataSource = this.cachedRecords.slice(
221+
this.pageInfo.pageSize * this.pageInfo.pageIndex,
222+
this.pageInfo.pageSize * (this.pageInfo.pageIndex + 1)
223+
);
224+
this.loading = loading;
225+
this.updating = false;
226+
if (setForm) {
227+
this.form = data.form;
228+
this.breadcrumbService.setBreadcrumb('@form', this.form.name as string);
229+
this.setDisplayedColumns();
230+
}
231+
}
232+
166233
/**
167234
* Handles page event.
168235
*
169236
* @param e page event.
170237
*/
171238
onPage(e: UIPageChangeEvent): void {
172-
this.pageInfo.pageIndex = e.pageIndex;
173-
if (
174-
e.pageIndex > e.previousPageIndex &&
175-
e.totalItems > this.cachedRecords.length &&
176-
ITEMS_PER_PAGE * this.pageInfo.pageIndex >= this.cachedRecords.length
177-
) {
178-
this.loadingMore = true;
179-
this.recordsQuery.refetch({
180-
id: this.id,
181-
first: ITEMS_PER_PAGE,
182-
afterCursor: this.pageInfo.endCursor,
183-
});
239+
const cachedData = handleTablePageEvent(
240+
e,
241+
this.pageInfo,
242+
this.cachedRecords
243+
);
244+
if (cachedData && cachedData.length === this.pageInfo.pageSize) {
245+
this.dataSource = cachedData;
184246
} else {
185-
this.dataSource = this.cachedRecords.slice(
186-
ITEMS_PER_PAGE * this.pageInfo.pageIndex,
187-
ITEMS_PER_PAGE * (this.pageInfo.pageIndex + 1)
188-
);
247+
this.fetchRecordsData();
189248
}
190249
}
191250

@@ -392,7 +451,7 @@ export class FormRecordsComponent
392451
'models.record.notifications.uploadSuccessful'
393452
)
394453
);
395-
this.getFormData();
454+
this.fetchRecordsData(true);
396455
this.showUpload = false;
397456
}
398457
},
@@ -411,7 +470,7 @@ export class FormRecordsComponent
411470
onSwitchView(e: any): void {
412471
e.stopPropagation();
413472
this.showDeletedRecords = !this.showDeletedRecords;
414-
this.getFormData();
473+
this.fetchRecordsData(true);
415474
}
416475

417476
/**

apps/web-widgets/src/app/widgets/app-widget/app-widget.component.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import { debounceTime } from 'rxjs';
1919
import { isEmpty } from 'lodash';
2020
import { Router } from '@angular/router';
21-
import { Location, LocationStrategy } from '@angular/common';
21+
import { Location } from '@angular/common';
2222
import { ShadowDomService } from '@oort-front/ui';
2323

2424
/**
@@ -56,13 +56,25 @@ export class AppWidgetComponent
5656
this.onToggleFilter(opened);
5757
}
5858

59+
/** Navigation path */
5960
@Input()
6061
set path(value: string) {
6162
this.router.navigate([value]);
6263
}
6364

65+
/** Pass new value to the filter */
66+
@Input()
67+
set filter(value: any) {
68+
this.contextService.filter.next(value);
69+
}
70+
71+
/** Is filter active */
6472
@Output()
6573
filterActive$ = new EventEmitter<boolean>();
74+
/** Emit filter value */
75+
@Output()
76+
filter$ = new EventEmitter<any>();
77+
/** Available pages */
6678
@Output()
6779
pages = new EventEmitter<any[]>();
6880

@@ -72,6 +84,10 @@ export class AppWidgetComponent
7284
* @param el class related element reference
7385
* @param injector angular application injector
7486
* @param contextService Shared context service
87+
* @param router Angular routter
88+
* @param applicationService Shared application service
89+
* @param location Angular location
90+
* @param shadowDomService Shared shadow dom service
7591
*/
7692
constructor(
7793
el: ElementRef,
@@ -80,13 +96,13 @@ export class AppWidgetComponent
8096
private router: Router,
8197
private applicationService: ApplicationService,
8298
private location: Location,
83-
private locationStrategy: LocationStrategy,
8499
private shadowDomService: ShadowDomService
85100
) {
86101
super(el, injector);
87102
this.shadowDomService.shadowRoot = el.nativeElement.shadowRoot;
88103
this.contextService.filter$.pipe(debounceTime(500)).subscribe((value) => {
89104
this.filterActive$.emit(!isEmpty(value));
105+
this.filter$.emit(value);
90106
});
91107
this.applicationService.application$.subscribe(
92108
(application: Application | null) => {

apps/web-widgets/src/app/widgets/app-widget/application/application.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class ApplicationComponent
3131
public hideMenu = false;
3232
/** Is large device */
3333
public largeDevice: boolean;
34-
/** Is loading */
34+
/** Loading indicator */
3535
public loading = true;
3636

3737
/**

libs/shared/src/lib/components/aggregation/aggregation-grid/aggregation-grid.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ export class AggregationGridComponent
102102
.subscribe(() => {
103103
this.getAggregationData();
104104
});
105-
this.getAggregationFields();
105+
this.queryBuilder.isDoneLoading$.subscribe((doneLoading) => {
106+
if (doneLoading) {
107+
this.getAggregationFields();
108+
}
109+
});
106110
}
107111

108112
ngOnChanges(): void {

libs/shared/src/lib/components/ui/core-grid/grid/grid.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,12 @@ export class GridComponent
11571157
});
11581158
// If aggregation, set the width of the columns here (cannot use layout parameters)
11591159
if (this.useAggregation) {
1160+
this.columns.forEach((column) =>
1161+
this.grid?.reorderColumn(
1162+
column,
1163+
this.fields.findIndex((field: any) => field.name === column.field)
1164+
)
1165+
);
11601166
this.setColumnsWidth();
11611167
}
11621168
}

libs/shared/src/lib/services/query-builder/query-builder.service.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { Apollo, gql } from 'apollo-angular';
22
import { Injectable } from '@angular/core';
3-
import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs';
3+
import {
4+
BehaviorSubject,
5+
firstValueFrom,
6+
Observable,
7+
ReplaySubject,
8+
} from 'rxjs';
49
import { GET_QUERY_META_DATA, GET_QUERY_TYPES } from './graphql/queries';
510
import { ApolloQueryResult } from '@apollo/client';
611
import get from 'lodash/get';
@@ -101,6 +106,11 @@ export class QueryBuilderService {
101106
return this.availableTypes.asObservable();
102107
}
103108

109+
/** Loading indicator that asserts whether available queries are done loading */
110+
private isDoneLoading = new ReplaySubject<boolean>();
111+
/** Loading indicator as observable */
112+
public isDoneLoading$ = this.isDoneLoading.asObservable();
113+
104114
/** User fields */
105115
private userFields = [];
106116

@@ -111,20 +121,19 @@ export class QueryBuilderService {
111121
* @param apollo Apollo client
112122
*/
113123
constructor(private apollo: Apollo) {
124+
this.isDoneLoading.next(false);
114125
this.apollo
115126
.query<QueryTypes>({
116127
query: GET_QUERY_TYPES,
117128
})
118129
.subscribe(({ data }) => {
119-
// eslint-disable-next-line no-underscore-dangle
130+
this.isDoneLoading.next(true);
120131
this.availableTypes.next(data.__schema.types);
121132
this.availableQueries.next(
122-
// eslint-disable-next-line no-underscore-dangle
123133
data.__schema.queryType.fields.filter((x: any) =>
124134
x.name.startsWith('all')
125135
)
126136
);
127-
// eslint-disable-next-line no-underscore-dangle
128137
this.userFields = data.__schema.types
129138
.find((x: any) => x.name === 'User')
130139
.fields.filter((x: any) => USER_FIELDS.includes(x.name));

0 commit comments

Comments
 (0)