http-request-manager 18.16.1 → 18.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -190,19 +190,32 @@ class UtilsService {
|
|
|
190
190
|
switch (type) {
|
|
191
191
|
case 'y':
|
|
192
192
|
const years = parseInt(str.slice(0, -1));
|
|
193
|
-
|
|
193
|
+
const dateY = new Date();
|
|
194
|
+
dateY.setFullYear(dateY.getFullYear() + years, 0, 1);
|
|
195
|
+
dateY.setHours(0, 0, 0, 0);
|
|
196
|
+
value = Math.floor(dateY.getTime() / 1000);
|
|
194
197
|
break;
|
|
195
198
|
case 'm':
|
|
196
199
|
const months = parseInt(str.slice(0, -1));
|
|
197
|
-
|
|
200
|
+
const dateM = new Date();
|
|
201
|
+
dateM.setMonth(dateM.getMonth() + months, 1);
|
|
202
|
+
dateM.setHours(0, 0, 0, 0);
|
|
203
|
+
value = Math.floor(dateM.getTime() / 1000);
|
|
198
204
|
break;
|
|
199
205
|
case 'w':
|
|
200
206
|
const weeks = parseInt(str.slice(0, -1));
|
|
201
|
-
|
|
207
|
+
const dateW = new Date();
|
|
208
|
+
const daysUntilSunday = (7 - dateW.getDay()) % 7;
|
|
209
|
+
dateW.setDate(dateW.getDate() + daysUntilSunday + 1 + (weeks - 1) * 7);
|
|
210
|
+
dateW.setHours(0, 0, 0, 0);
|
|
211
|
+
value = Math.floor(dateW.getTime() / 1000);
|
|
202
212
|
break;
|
|
203
213
|
case 'd':
|
|
204
214
|
const days = parseInt(str.slice(0, -1));
|
|
205
|
-
|
|
215
|
+
const dateD = new Date();
|
|
216
|
+
dateD.setDate(dateD.getDate() + days);
|
|
217
|
+
dateD.setHours(0, 0, 0, 0);
|
|
218
|
+
value = Math.floor(dateD.getTime() / 1000);
|
|
206
219
|
break;
|
|
207
220
|
case 'hr':
|
|
208
221
|
const hrs = parseInt(str.slice(0, -2));
|
|
@@ -3930,13 +3943,15 @@ class HTTPManagerService extends RequestService {
|
|
|
3930
3943
|
return this.createObservable(updatedOptions, requests, func.name)
|
|
3931
3944
|
.pipe(tap(data => {
|
|
3932
3945
|
this.data.next(data);
|
|
3933
|
-
if (updatedOptions.displaySuccess)
|
|
3946
|
+
if (updatedOptions.displaySuccess && !updatedOptions.stream)
|
|
3934
3947
|
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
3935
3948
|
}), finalize(() => {
|
|
3936
3949
|
this.streamProgress.next({
|
|
3937
3950
|
...this.streamProgress.value,
|
|
3938
3951
|
stage: 'complete'
|
|
3939
3952
|
});
|
|
3953
|
+
if (updatedOptions.displaySuccess && updatedOptions.stream)
|
|
3954
|
+
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
3940
3955
|
this.isPending.next(false);
|
|
3941
3956
|
}), catchError((err) => {
|
|
3942
3957
|
if (updatedOptions.displayError)
|
|
@@ -4366,7 +4381,9 @@ class RequestSignalsService extends WebsocketService {
|
|
|
4366
4381
|
}
|
|
4367
4382
|
requestStreamingOperator(options) {
|
|
4368
4383
|
return (source$) => {
|
|
4369
|
-
return source$.pipe(
|
|
4384
|
+
return source$.pipe(tap(output => {
|
|
4385
|
+
this.progress.set(output.progress.received);
|
|
4386
|
+
}), map(output => {
|
|
4370
4387
|
const data = output.data;
|
|
4371
4388
|
if (!data || (Array.isArray(data) && data.length === 0)) {
|
|
4372
4389
|
return data;
|
|
@@ -4726,9 +4743,13 @@ class HTTPManagerSignalsService extends RequestSignalsService {
|
|
|
4726
4743
|
const requests = this.createRequest(func, updatedOptions);
|
|
4727
4744
|
return this.createObservable(updatedOptions, requests, func.name).pipe(tap(data => {
|
|
4728
4745
|
this.data.set(data);
|
|
4729
|
-
if (updatedOptions.displaySuccess)
|
|
4746
|
+
if (updatedOptions.displaySuccess && !updatedOptions.stream)
|
|
4730
4747
|
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
4731
|
-
}), finalize(() =>
|
|
4748
|
+
}), finalize(() => {
|
|
4749
|
+
if (updatedOptions.displaySuccess && updatedOptions.stream)
|
|
4750
|
+
this.handleSuccessWithSnackBar(updatedOptions.successMessage);
|
|
4751
|
+
this.isPending.set(false);
|
|
4752
|
+
}), catchError((err) => {
|
|
4732
4753
|
if (updatedOptions.displayError)
|
|
4733
4754
|
this.handleErrorWithSnackBar(err, updatedOptions.errorMessage || err?.message);
|
|
4734
4755
|
this.isPending.set(false);
|
|
@@ -6471,19 +6492,16 @@ class DatabaseManagerService extends DbService {
|
|
|
6471
6492
|
}
|
|
6472
6493
|
clearTable(table) {
|
|
6473
6494
|
const tableName = this.cleanTableName(table);
|
|
6495
|
+
this.localStorageManager.deleteStore({ name: tableName });
|
|
6474
6496
|
try {
|
|
6475
6497
|
const tableInstance = this.table(tableName);
|
|
6476
6498
|
if (!tableInstance) {
|
|
6477
6499
|
console.warn(`clearTable: Table '${tableName}' not found`);
|
|
6478
6500
|
return of([]);
|
|
6479
6501
|
}
|
|
6480
|
-
// console.log(`clearTable: Clearing table '${tableName}'...`);
|
|
6481
|
-
// Use table.clear() directly and wrap in Observable
|
|
6482
6502
|
return from(Promise.resolve().then(() => {
|
|
6483
6503
|
return tableInstance.clear();
|
|
6484
|
-
})).pipe(
|
|
6485
|
-
// tap(() => console.log(`clearTable: ✅ Table '${tableName}' cleared successfully`)),
|
|
6486
|
-
map(() => []));
|
|
6504
|
+
})).pipe(map(() => []));
|
|
6487
6505
|
}
|
|
6488
6506
|
catch (error) {
|
|
6489
6507
|
console.error(`clearTable: ❌ Error:`, error);
|
|
@@ -8110,7 +8128,6 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8110
8128
|
this._requestCachePaths.set(tableName, this.resolvePath(options?.path).filter(p => typeof p === 'string' || typeof p === 'number').map(String));
|
|
8111
8129
|
this.localStorageManagerService.store$(tableName).pipe(take(1), tap((storeData) => {
|
|
8112
8130
|
const currentCache = storeData?.requestCache || {};
|
|
8113
|
-
const currentEntry = currentCache[type] || {};
|
|
8114
8131
|
this.localStorageManagerService.updateStore({
|
|
8115
8132
|
name: tableName,
|
|
8116
8133
|
data: {
|
|
@@ -8118,13 +8135,11 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8118
8135
|
requestCache: {
|
|
8119
8136
|
...currentCache,
|
|
8120
8137
|
[type]: {
|
|
8121
|
-
...
|
|
8138
|
+
...(currentCache[type] || {}),
|
|
8122
8139
|
signature,
|
|
8123
8140
|
savedAt: Date.now(),
|
|
8124
8141
|
path: this.resolvePath(options?.path),
|
|
8125
|
-
headers: this.filterHeaders(options?.headers)
|
|
8126
|
-
queryParams: currentEntry.queryParams,
|
|
8127
|
-
queryParamsExpires: currentEntry.queryParamsExpires,
|
|
8142
|
+
headers: this.filterHeaders(options?.headers)
|
|
8128
8143
|
}
|
|
8129
8144
|
}
|
|
8130
8145
|
}
|
|
@@ -8266,53 +8281,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8266
8281
|
const ignoreQueryParams = Array.isArray(options?.ignoreQueryParams) ? options.ignoreQueryParams : [];
|
|
8267
8282
|
if (!normalized.hasQuery) {
|
|
8268
8283
|
const meta = this.getRequestCacheMetadata(storeData, type);
|
|
8269
|
-
if (!meta) {
|
|
8270
|
-
// No prior cache entry — record that we're tracking this request
|
|
8271
|
-
this.setCachedRequestSignature(tableName, type, '');
|
|
8272
|
-
this.localStorageManagerService.store$(tableName).pipe(take(1), tap((s) => {
|
|
8273
|
-
const currentCache = s?.requestCache || {};
|
|
8274
|
-
this.localStorageManagerService.updateStore({
|
|
8275
|
-
name: tableName,
|
|
8276
|
-
data: {
|
|
8277
|
-
...(s || {}),
|
|
8278
|
-
requestCache: {
|
|
8279
|
-
...currentCache,
|
|
8280
|
-
[type]: {
|
|
8281
|
-
...(currentCache[type] || {}),
|
|
8282
|
-
active: true,
|
|
8283
|
-
}
|
|
8284
|
-
}
|
|
8285
|
-
}
|
|
8286
|
-
});
|
|
8287
|
-
})).subscribe();
|
|
8288
|
-
}
|
|
8289
8284
|
return of(!meta);
|
|
8290
8285
|
}
|
|
8291
8286
|
const filtered = this.trackerFilterQuery(normalized.query, ignoreQueryParams);
|
|
8292
8287
|
const keys = Object.keys(filtered);
|
|
8293
8288
|
if (keys.length === 0) {
|
|
8294
|
-
|
|
8295
|
-
const meta = this.getRequestCacheMetadata(storeData, type);
|
|
8296
|
-
if (!meta) {
|
|
8297
|
-
this.setCachedRequestSignature(tableName, type, '');
|
|
8298
|
-
this.localStorageManagerService.store$(tableName).pipe(take(1), tap((s) => {
|
|
8299
|
-
const currentCache = s?.requestCache || {};
|
|
8300
|
-
this.localStorageManagerService.updateStore({
|
|
8301
|
-
name: tableName,
|
|
8302
|
-
data: {
|
|
8303
|
-
...(s || {}),
|
|
8304
|
-
requestCache: {
|
|
8305
|
-
...currentCache,
|
|
8306
|
-
[type]: {
|
|
8307
|
-
...(currentCache[type] || {}),
|
|
8308
|
-
active: true,
|
|
8309
|
-
}
|
|
8310
|
-
}
|
|
8311
|
-
}
|
|
8312
|
-
});
|
|
8313
|
-
})).subscribe();
|
|
8314
|
-
}
|
|
8315
|
-
return of(!meta);
|
|
8289
|
+
return of(!this.getRequestCacheMetadata(storeData, type));
|
|
8316
8290
|
}
|
|
8317
8291
|
const meta = this.getRequestCacheMetadata(storeData, type) || {};
|
|
8318
8292
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -9027,7 +9001,7 @@ class QueryPlanner {
|
|
|
9027
9001
|
}
|
|
9028
9002
|
else {
|
|
9029
9003
|
const projected = columns
|
|
9030
|
-
.filter((c) => c.expr?.type === 'column_ref')
|
|
9004
|
+
.filter((c) => c.expr?.type === 'column_ref' && c.expr?.column !== '*')
|
|
9031
9005
|
.map((c) => c.expr.column);
|
|
9032
9006
|
plan.projection = projected.length > 0 ? projected : null;
|
|
9033
9007
|
}
|
|
@@ -12674,11 +12648,11 @@ class DatabaseDataDemoComponent {
|
|
|
12674
12648
|
});
|
|
12675
12649
|
}
|
|
12676
12650
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatabaseDataDemoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12677
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DatabaseDataDemoComponent, selector: "app-database-data-demo", ngImport: i0, template: "<div style=\"padding: 2rem;\">\n\n <h2>\n Database Manager Service Demo\n </h2>\n\n <div style=\"margin-bottom: 1rem; display: flex; gap: 1rem;\">\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"clearAllData()\"\n >\n Clear Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"updateData()\"\n >\n Update Data\n </button>\n <div style=\"flex:1\"></div>\n <button\n mat-stroked-button\n color=\"warn\"\n [disabled]=\"!dataToDisplay.length\"\n (click)=\"removeData()\"\n >\n Remove Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"addData()\"\n >\n Add Data\n </button>\n </div>\n\n <div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource\">\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef>ID</th>\n <td mat-cell *matCellDef=\"let element\">{{element.id}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\n <td mat-cell *matCellDef=\"let element\">{{element.last_name}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef>Age</th>\n <td mat-cell *matCellDef=\"let element\">{{element.age}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef>Amount</th>\n <td mat-cell *matCellDef=\"let element\">{{element.amount | currency}}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- \u2500\u2500 SQL Query Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <mat-divider style=\"margin: 2rem 0;\"></mat-divider>\n\n <h3 style=\"margin-bottom: 1rem;\">SQL Query with DexieJS</h3>\n\n <div style=\"display: flex; gap: 1rem; align-items: flex-start;\">\n <mat-form-field style=\"flex: 1;\" appearance=\"outline\">\n <mat-label>SQL Query</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"sqlQuery\"\n rows=\"3\"\n placeholder=\"e.g. SELECT * FROM sample_table WHERE age > 20\"\n (keydown.control.enter)=\"runSqlQuery()\"\n ></textarea>\n
|
|
12651
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: DatabaseDataDemoComponent, selector: "app-database-data-demo", ngImport: i0, template: "<div style=\"padding: 2rem;\">\n\n <h2>\n Database Manager Service Demo\n </h2>\n\n <div style=\"margin-bottom: 1rem; display: flex; gap: 1rem;\">\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"clearAllData()\"\n >\n Clear Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"updateData()\"\n >\n Update Data\n </button>\n <div style=\"flex:1\"></div>\n <button\n mat-stroked-button\n color=\"warn\"\n [disabled]=\"!dataToDisplay.length\"\n (click)=\"removeData()\"\n >\n Remove Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"addData()\"\n >\n Add Data\n </button>\n </div>\n\n <div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource\">\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef>ID</th>\n <td mat-cell *matCellDef=\"let element\">{{element.id}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\n <td mat-cell *matCellDef=\"let element\">{{element.last_name}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef>Age</th>\n <td mat-cell *matCellDef=\"let element\">{{element.age}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef>Amount</th>\n <td mat-cell *matCellDef=\"let element\">{{element.amount | currency}}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- \u2500\u2500 SQL Query Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <mat-divider style=\"margin: 2rem 0;\"></mat-divider>\n\n <h3 style=\"margin-bottom: 1rem;\">SQL Query with DexieJS</h3>\n\n <div style=\"display: flex; gap: 1rem; align-items: flex-start;\">\n <mat-form-field style=\"flex: 1;\" appearance=\"outline\">\n <mat-label>SQL Query</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"sqlQuery\"\n rows=\"3\"\n placeholder=\"e.g. SELECT * FROM sample_table WHERE age > 20\"\n (keydown.control.enter)=\"runSqlQuery()\"\n ></textarea>\n </mat-form-field>\n </div>\n\n <div style=\"display: flex;\">\n <div style=\"flex:1\"></div>\n <button\n mat-flat-button\n color=\"primary\"\n style=\"margin-top: 4px;\"\n [disabled]=\"sqlLoading || !sqlQuery.trim()\"\n (click)=\"runSqlQuery()\"\n >\n {{ sqlLoading ? 'Running\u2026' : 'Execute' }}\n </button>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <!-- Error -->\n <div *ngIf=\"sqlError\" style=\"color: #d32f2f; margin: 0.5rem 0 1rem; font-size: 0.875rem;\">\n <mat-icon style=\"vertical-align: middle; font-size: 16px; height: 16px; width: 16px;\">error</mat-icon>\n {{ sqlError }}\n </div>\n\n <!-- Results table (dynamic columns) -->\n <div *ngIf=\"!sqlLoading && sqlResults.length > 0\" class=\"table-container\" style=\"margin-top: 1rem;\">\n <div>\n {{ sqlResults | json }}\n </div>\n <p style=\"font-size: 0.8rem; color: #666; margin-top: 0.5rem;\">\n {{ sqlResults.length }} row{{ sqlResults.length === 1 ? '' : 's' }} returned\n </p>\n </div>\n\n <!-- Empty state -->\n <p *ngIf=\"!sqlLoading && !sqlError && sqlResults.length === 0 && sqlQuery.trim()\"\n style=\"color: #888; font-size: 0.875rem; margin-top: 0.5rem;\">\n No results to display. Execute a query above.\n </p>\n\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i1$1.CurrencyPipe, name: "currency" }] }); }
|
|
12678
12652
|
}
|
|
12679
12653
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatabaseDataDemoComponent, decorators: [{
|
|
12680
12654
|
type: Component,
|
|
12681
|
-
args: [{ selector: 'app-database-data-demo', standalone: false, template: "<div style=\"padding: 2rem;\">\n\n <h2>\n Database Manager Service Demo\n </h2>\n\n <div style=\"margin-bottom: 1rem; display: flex; gap: 1rem;\">\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"clearAllData()\"\n >\n Clear Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"updateData()\"\n >\n Update Data\n </button>\n <div style=\"flex:1\"></div>\n <button\n mat-stroked-button\n color=\"warn\"\n [disabled]=\"!dataToDisplay.length\"\n (click)=\"removeData()\"\n >\n Remove Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"addData()\"\n >\n Add Data\n </button>\n </div>\n\n <div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource\">\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef>ID</th>\n <td mat-cell *matCellDef=\"let element\">{{element.id}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\n <td mat-cell *matCellDef=\"let element\">{{element.last_name}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef>Age</th>\n <td mat-cell *matCellDef=\"let element\">{{element.age}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef>Amount</th>\n <td mat-cell *matCellDef=\"let element\">{{element.amount | currency}}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- \u2500\u2500 SQL Query Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <mat-divider style=\"margin: 2rem 0;\"></mat-divider>\n\n <h3 style=\"margin-bottom: 1rem;\">SQL Query with DexieJS</h3>\n\n <div style=\"display: flex; gap: 1rem; align-items: flex-start;\">\n <mat-form-field style=\"flex: 1;\" appearance=\"outline\">\n <mat-label>SQL Query</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"sqlQuery\"\n rows=\"3\"\n placeholder=\"e.g. SELECT * FROM sample_table WHERE age > 20\"\n (keydown.control.enter)=\"runSqlQuery()\"\n ></textarea>\n
|
|
12655
|
+
args: [{ selector: 'app-database-data-demo', standalone: false, template: "<div style=\"padding: 2rem;\">\n\n <h2>\n Database Manager Service Demo\n </h2>\n\n <div style=\"margin-bottom: 1rem; display: flex; gap: 1rem;\">\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"clearAllData()\"\n >\n Clear Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"updateData()\"\n >\n Update Data\n </button>\n <div style=\"flex:1\"></div>\n <button\n mat-stroked-button\n color=\"warn\"\n [disabled]=\"!dataToDisplay.length\"\n (click)=\"removeData()\"\n >\n Remove Data\n </button>\n <button mat-stroked-button\n color=\"primary\"\n (click)=\"addData()\"\n >\n Add Data\n </button>\n </div>\n\n <div class=\"table-container\">\n <table mat-table [dataSource]=\"dataSource\">\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef>ID</th>\n <td mat-cell *matCellDef=\"let element\">{{element.id}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"last_name\">\n <th mat-header-cell *matHeaderCellDef>Last Name</th>\n <td mat-cell *matCellDef=\"let element\">{{element.last_name}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"age\">\n <th mat-header-cell *matHeaderCellDef>Age</th>\n <td mat-cell *matCellDef=\"let element\">{{element.age}}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef>Amount</th>\n <td mat-cell *matCellDef=\"let element\">{{element.amount | currency}}</td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </div>\n\n <!-- \u2500\u2500 SQL Query Section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n <mat-divider style=\"margin: 2rem 0;\"></mat-divider>\n\n <h3 style=\"margin-bottom: 1rem;\">SQL Query with DexieJS</h3>\n\n <div style=\"display: flex; gap: 1rem; align-items: flex-start;\">\n <mat-form-field style=\"flex: 1;\" appearance=\"outline\">\n <mat-label>SQL Query</mat-label>\n <textarea\n matInput\n [(ngModel)]=\"sqlQuery\"\n rows=\"3\"\n placeholder=\"e.g. SELECT * FROM sample_table WHERE age > 20\"\n (keydown.control.enter)=\"runSqlQuery()\"\n ></textarea>\n </mat-form-field>\n </div>\n\n <div style=\"display: flex;\">\n <div style=\"flex:1\"></div>\n <button\n mat-flat-button\n color=\"primary\"\n style=\"margin-top: 4px;\"\n [disabled]=\"sqlLoading || !sqlQuery.trim()\"\n (click)=\"runSqlQuery()\"\n >\n {{ sqlLoading ? 'Running\u2026' : 'Execute' }}\n </button>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <!-- Error -->\n <div *ngIf=\"sqlError\" style=\"color: #d32f2f; margin: 0.5rem 0 1rem; font-size: 0.875rem;\">\n <mat-icon style=\"vertical-align: middle; font-size: 16px; height: 16px; width: 16px;\">error</mat-icon>\n {{ sqlError }}\n </div>\n\n <!-- Results table (dynamic columns) -->\n <div *ngIf=\"!sqlLoading && sqlResults.length > 0\" class=\"table-container\" style=\"margin-top: 1rem;\">\n <div>\n {{ sqlResults | json }}\n </div>\n <p style=\"font-size: 0.8rem; color: #666; margin-top: 0.5rem;\">\n {{ sqlResults.length }} row{{ sqlResults.length === 1 ? '' : 's' }} returned\n </p>\n </div>\n\n <!-- Empty state -->\n <p *ngIf=\"!sqlLoading && !sqlError && sqlResults.length === 0 && sqlQuery.trim()\"\n style=\"color: #888; font-size: 0.875rem; margin-top: 0.5rem;\">\n No results to display. Execute a query above.\n </p>\n\n</div>\n" }]
|
|
12682
12656
|
}], ctorParameters: () => [] });
|
|
12683
12657
|
class DatabaseDataSource extends DataSource {
|
|
12684
12658
|
constructor(initialData) {
|