@snteam/amplify-angular-core 1.0.42 → 1.0.44
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.
|
@@ -2546,6 +2546,11 @@ class AmplifyModelService {
|
|
|
2546
2546
|
// Final fallback - use a simple, predictable selection set
|
|
2547
2547
|
const fallbackSelectionSet = this.generateSimpleFallbackSelectionSet(config);
|
|
2548
2548
|
console.log('AmplifyModelService: Using simple fallback selection set:', fallbackSelectionSet);
|
|
2549
|
+
// Ensure we never return an empty array
|
|
2550
|
+
if (fallbackSelectionSet.length === 0) {
|
|
2551
|
+
console.warn('AmplifyModelService: Fallback selection set is empty, using minimal default');
|
|
2552
|
+
return ['id'];
|
|
2553
|
+
}
|
|
2549
2554
|
return fallbackSelectionSet;
|
|
2550
2555
|
}
|
|
2551
2556
|
catch (error) {
|
|
@@ -2587,13 +2592,15 @@ class AmplifyModelService {
|
|
|
2587
2592
|
generateSimpleFallbackSelectionSet(config) {
|
|
2588
2593
|
const selectionSet = ['id'];
|
|
2589
2594
|
if (config.fieldName) {
|
|
2590
|
-
// Add the relationship field itself
|
|
2595
|
+
// Add the relationship field itself with basic nested fields
|
|
2591
2596
|
selectionSet.push(config.fieldName);
|
|
2592
|
-
// Add common nested fields
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2597
|
+
// Add common nested fields that are likely to exist
|
|
2598
|
+
const commonFields = ['id', 'name', 'title', 'label', 'description'];
|
|
2599
|
+
for (const field of commonFields) {
|
|
2600
|
+
selectionSet.push(`${config.fieldName}.${field}`);
|
|
2601
|
+
}
|
|
2596
2602
|
}
|
|
2603
|
+
console.log('AmplifyModelService: Generated simple fallback selection set:', selectionSet);
|
|
2597
2604
|
return selectionSet;
|
|
2598
2605
|
}
|
|
2599
2606
|
setRelatedSub(config, baseId) {
|
|
@@ -5156,6 +5163,7 @@ class ConfigurationsComponent {
|
|
|
5156
5163
|
hasFormView = false;
|
|
5157
5164
|
hasListView = false;
|
|
5158
5165
|
hasFieldConfig = false;
|
|
5166
|
+
hasRelationshipConfig = false;
|
|
5159
5167
|
// Relationship configuration management
|
|
5160
5168
|
relationshipConfigs = [];
|
|
5161
5169
|
showAddRelationshipConfig = false;
|
|
@@ -5190,11 +5198,13 @@ class ConfigurationsComponent {
|
|
|
5190
5198
|
this.hasFormView = 'FormView' in models;
|
|
5191
5199
|
this.hasListView = 'ListView' in models;
|
|
5192
5200
|
this.hasFieldConfig = 'FieldConfig' in models;
|
|
5201
|
+
this.hasRelationshipConfig = 'RelationshipConfig' in models;
|
|
5193
5202
|
console.log('ConfigurationsComponent: Model availability:', {
|
|
5194
5203
|
TableConfig: this.hasTableConfig,
|
|
5195
5204
|
FormView: this.hasFormView,
|
|
5196
5205
|
ListView: this.hasListView,
|
|
5197
|
-
FieldConfig: this.hasFieldConfig
|
|
5206
|
+
FieldConfig: this.hasFieldConfig,
|
|
5207
|
+
RelationshipConfig: this.hasRelationshipConfig
|
|
5198
5208
|
});
|
|
5199
5209
|
}
|
|
5200
5210
|
async populateDefaultFieldConfigs() {
|
|
@@ -5507,7 +5517,41 @@ return fields;
|
|
|
5507
5517
|
console.log('ConfigurationsComponent: Available relationship fields for', modelName, ':', this.availableFields);
|
|
5508
5518
|
}
|
|
5509
5519
|
loadRelationshipConfigs() {
|
|
5510
|
-
|
|
5520
|
+
if (!this.hasRelationshipConfig) {
|
|
5521
|
+
console.warn('ConfigurationsComponent: RelationshipConfig model not available, falling back to localStorage');
|
|
5522
|
+
this.loadRelationshipConfigsFromLocalStorage();
|
|
5523
|
+
return;
|
|
5524
|
+
}
|
|
5525
|
+
// Load from Amplify RelationshipConfig model
|
|
5526
|
+
const observable = this.ams.listItemsForModel('RelationshipConfig');
|
|
5527
|
+
if (!observable) {
|
|
5528
|
+
console.error('ConfigurationsComponent: Failed to get RelationshipConfig observable');
|
|
5529
|
+
this.loadRelationshipConfigsFromLocalStorage();
|
|
5530
|
+
return;
|
|
5531
|
+
}
|
|
5532
|
+
observable.subscribe({
|
|
5533
|
+
next: ({ items }) => {
|
|
5534
|
+
this.relationshipConfigs = items
|
|
5535
|
+
.filter((item) => item.isActive !== false)
|
|
5536
|
+
.map((item) => ({
|
|
5537
|
+
id: item.id,
|
|
5538
|
+
relationshipModel: item.relationshipModel,
|
|
5539
|
+
fieldName: item.fieldName,
|
|
5540
|
+
selectionSet: item.selectionSet || [],
|
|
5541
|
+
description: item.description
|
|
5542
|
+
}));
|
|
5543
|
+
console.log('ConfigurationsComponent: Loaded relationship configs from Amplify:', this.relationshipConfigs);
|
|
5544
|
+
// Update the AmplifyModelService with loaded configurations
|
|
5545
|
+
this.updateAmplifyModelService();
|
|
5546
|
+
},
|
|
5547
|
+
error: (error) => {
|
|
5548
|
+
console.error('ConfigurationsComponent: Error loading relationship configs from Amplify:', error);
|
|
5549
|
+
this.loadRelationshipConfigsFromLocalStorage();
|
|
5550
|
+
}
|
|
5551
|
+
});
|
|
5552
|
+
}
|
|
5553
|
+
loadRelationshipConfigsFromLocalStorage() {
|
|
5554
|
+
// Fallback to localStorage for backward compatibility
|
|
5511
5555
|
const stored = localStorage.getItem('snteam-relationship-configs');
|
|
5512
5556
|
if (stored) {
|
|
5513
5557
|
try {
|
|
@@ -5516,10 +5560,10 @@ return fields;
|
|
|
5516
5560
|
...rel,
|
|
5517
5561
|
id: rel.id || this.generateId()
|
|
5518
5562
|
}));
|
|
5519
|
-
console.log('ConfigurationsComponent: Loaded relationship configs:', this.relationshipConfigs);
|
|
5563
|
+
console.log('ConfigurationsComponent: Loaded relationship configs from localStorage:', this.relationshipConfigs);
|
|
5520
5564
|
}
|
|
5521
5565
|
catch (error) {
|
|
5522
|
-
console.error('ConfigurationsComponent: Error loading relationship configs:', error);
|
|
5566
|
+
console.error('ConfigurationsComponent: Error loading relationship configs from localStorage:', error);
|
|
5523
5567
|
this.relationshipConfigs = [];
|
|
5524
5568
|
}
|
|
5525
5569
|
}
|
|
@@ -5528,6 +5572,7 @@ return fields;
|
|
|
5528
5572
|
}
|
|
5529
5573
|
}
|
|
5530
5574
|
saveRelationshipConfigsToStorage() {
|
|
5575
|
+
// Always update localStorage for backward compatibility
|
|
5531
5576
|
const config = {
|
|
5532
5577
|
relationships: this.relationshipConfigs.map(({ id, ...config }) => config),
|
|
5533
5578
|
defaultSelectionSet: ['id'],
|
|
@@ -5535,10 +5580,19 @@ return fields;
|
|
|
5535
5580
|
};
|
|
5536
5581
|
localStorage.setItem('snteam-relationship-configs', JSON.stringify(config));
|
|
5537
5582
|
// Update the AmplifyModelService with the new configuration
|
|
5538
|
-
this.
|
|
5583
|
+
this.updateAmplifyModelService();
|
|
5539
5584
|
console.log('ConfigurationsComponent: Saved relationship configs to storage and updated service');
|
|
5540
5585
|
}
|
|
5541
|
-
|
|
5586
|
+
updateAmplifyModelService() {
|
|
5587
|
+
const config = {
|
|
5588
|
+
relationships: this.relationshipConfigs.map(({ id, ...config }) => config),
|
|
5589
|
+
defaultSelectionSet: ['id'],
|
|
5590
|
+
enableFallback: true
|
|
5591
|
+
};
|
|
5592
|
+
this.ams.setRelationshipConfig(config);
|
|
5593
|
+
console.log('ConfigurationsComponent: Updated AmplifyModelService with relationship configs');
|
|
5594
|
+
}
|
|
5595
|
+
async saveRelationshipConfig() {
|
|
5542
5596
|
if (!this.relationshipConfigForm.valid) {
|
|
5543
5597
|
this.snackBar.open('Please fill in all required fields', 'Dismiss', { duration: 3000 });
|
|
5544
5598
|
return;
|
|
@@ -5549,35 +5603,98 @@ return fields;
|
|
|
5549
5603
|
.split('\n')
|
|
5550
5604
|
.map((line) => line.trim())
|
|
5551
5605
|
.filter((line) => line.length > 0);
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
const index = this.relationshipConfigs.findIndex(c => c.id === this.editingRelationshipConfig.id);
|
|
5562
|
-
if (index >= 0) {
|
|
5563
|
-
this.relationshipConfigs[index] = config;
|
|
5606
|
+
try {
|
|
5607
|
+
if (this.editingRelationshipConfig) {
|
|
5608
|
+
// Update existing configuration
|
|
5609
|
+
await this.updateRelationshipConfig(this.editingRelationshipConfig.id, {
|
|
5610
|
+
relationshipModel: formValue.relationshipModel,
|
|
5611
|
+
fieldName: formValue.fieldName,
|
|
5612
|
+
selectionSet: selectionSet,
|
|
5613
|
+
description: formValue.description || undefined
|
|
5614
|
+
});
|
|
5564
5615
|
this.snackBar.open('Relationship configuration updated successfully', 'Dismiss', { duration: 3000 });
|
|
5565
5616
|
}
|
|
5617
|
+
else {
|
|
5618
|
+
// Check for duplicate configuration
|
|
5619
|
+
const existing = this.relationshipConfigs.find(c => c.relationshipModel === formValue.relationshipModel &&
|
|
5620
|
+
c.fieldName === formValue.fieldName);
|
|
5621
|
+
if (existing) {
|
|
5622
|
+
this.snackBar.open('Configuration for this relationship already exists', 'Dismiss', { duration: 3000 });
|
|
5623
|
+
return;
|
|
5624
|
+
}
|
|
5625
|
+
// Create new configuration
|
|
5626
|
+
await this.createRelationshipConfig({
|
|
5627
|
+
relationshipModel: formValue.relationshipModel,
|
|
5628
|
+
fieldName: formValue.fieldName,
|
|
5629
|
+
selectionSet: selectionSet,
|
|
5630
|
+
description: formValue.description || undefined
|
|
5631
|
+
});
|
|
5632
|
+
this.snackBar.open('Relationship configuration added successfully', 'Dismiss', { duration: 3000 });
|
|
5633
|
+
}
|
|
5634
|
+
this.cancelRelationshipConfigEdit();
|
|
5635
|
+
}
|
|
5636
|
+
catch (error) {
|
|
5637
|
+
console.error('ConfigurationsComponent: Error saving relationship config:', error);
|
|
5638
|
+
this.snackBar.open('Error saving configuration: ' + error, 'Dismiss', { duration: 5000 });
|
|
5639
|
+
}
|
|
5640
|
+
}
|
|
5641
|
+
async createRelationshipConfig(config) {
|
|
5642
|
+
if (!this.hasRelationshipConfig) {
|
|
5643
|
+
// Fallback to localStorage if model not available
|
|
5644
|
+
const newConfig = {
|
|
5645
|
+
...config,
|
|
5646
|
+
id: this.generateId()
|
|
5647
|
+
};
|
|
5648
|
+
this.relationshipConfigs.push(newConfig);
|
|
5649
|
+
this.saveRelationshipConfigsToStorage();
|
|
5650
|
+
return;
|
|
5651
|
+
}
|
|
5652
|
+
const amplifyConfig = {
|
|
5653
|
+
relationshipModel: config.relationshipModel,
|
|
5654
|
+
fieldName: config.fieldName,
|
|
5655
|
+
selectionSet: config.selectionSet,
|
|
5656
|
+
description: config.description,
|
|
5657
|
+
isActive: true,
|
|
5658
|
+
createdAt: new Date().toISOString(),
|
|
5659
|
+
updatedAt: new Date().toISOString()
|
|
5660
|
+
};
|
|
5661
|
+
const result = await this.ams.createItemPromise('RelationshipConfig', amplifyConfig);
|
|
5662
|
+
if (result && result.data) {
|
|
5663
|
+
console.log('ConfigurationsComponent: Created RelationshipConfig in Amplify:', result.data);
|
|
5664
|
+
// Reload configurations to get the updated list
|
|
5665
|
+
this.loadRelationshipConfigs();
|
|
5566
5666
|
}
|
|
5567
5667
|
else {
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5668
|
+
throw new Error('Failed to create RelationshipConfig in Amplify');
|
|
5669
|
+
}
|
|
5670
|
+
}
|
|
5671
|
+
async updateRelationshipConfig(id, config) {
|
|
5672
|
+
if (!this.hasRelationshipConfig) {
|
|
5673
|
+
// Fallback to localStorage if model not available
|
|
5674
|
+
const index = this.relationshipConfigs.findIndex(c => c.id === id);
|
|
5675
|
+
if (index >= 0) {
|
|
5676
|
+
this.relationshipConfigs[index] = { ...config, id };
|
|
5677
|
+
this.saveRelationshipConfigsToStorage();
|
|
5574
5678
|
}
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5679
|
+
return;
|
|
5680
|
+
}
|
|
5681
|
+
const amplifyConfig = {
|
|
5682
|
+
id: id,
|
|
5683
|
+
relationshipModel: config.relationshipModel,
|
|
5684
|
+
fieldName: config.fieldName,
|
|
5685
|
+
selectionSet: config.selectionSet,
|
|
5686
|
+
description: config.description,
|
|
5687
|
+
updatedAt: new Date().toISOString()
|
|
5688
|
+
};
|
|
5689
|
+
const result = await this.ams.updateItemForModel('RelationshipConfig', amplifyConfig);
|
|
5690
|
+
if (result && result.data) {
|
|
5691
|
+
console.log('ConfigurationsComponent: Updated RelationshipConfig in Amplify:', result.data);
|
|
5692
|
+
// Reload configurations to get the updated list
|
|
5693
|
+
this.loadRelationshipConfigs();
|
|
5694
|
+
}
|
|
5695
|
+
else {
|
|
5696
|
+
throw new Error('Failed to update RelationshipConfig in Amplify');
|
|
5578
5697
|
}
|
|
5579
|
-
this.saveRelationshipConfigsToStorage();
|
|
5580
|
-
this.cancelRelationshipConfigEdit();
|
|
5581
5698
|
}
|
|
5582
5699
|
editRelationshipConfig(config) {
|
|
5583
5700
|
this.editingRelationshipConfig = config;
|
|
@@ -5592,12 +5709,32 @@ return fields;
|
|
|
5592
5709
|
description: config.description || ''
|
|
5593
5710
|
});
|
|
5594
5711
|
}
|
|
5595
|
-
deleteRelationshipConfig(config) {
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5712
|
+
async deleteRelationshipConfig(config) {
|
|
5713
|
+
try {
|
|
5714
|
+
if (!this.hasRelationshipConfig) {
|
|
5715
|
+
// Fallback to localStorage if model not available
|
|
5716
|
+
const index = this.relationshipConfigs.findIndex(c => c.id === config.id);
|
|
5717
|
+
if (index >= 0) {
|
|
5718
|
+
this.relationshipConfigs.splice(index, 1);
|
|
5719
|
+
this.saveRelationshipConfigsToStorage();
|
|
5720
|
+
this.snackBar.open('Relationship configuration deleted', 'Dismiss', { duration: 3000 });
|
|
5721
|
+
}
|
|
5722
|
+
return;
|
|
5723
|
+
}
|
|
5724
|
+
const result = await this.ams.deleteItemForModel('RelationshipConfig', config.id);
|
|
5725
|
+
if (result && result.data) {
|
|
5726
|
+
console.log('ConfigurationsComponent: Deleted RelationshipConfig from Amplify:', result.data);
|
|
5727
|
+
// Reload configurations to get the updated list
|
|
5728
|
+
this.loadRelationshipConfigs();
|
|
5729
|
+
this.snackBar.open('Relationship configuration deleted', 'Dismiss', { duration: 3000 });
|
|
5730
|
+
}
|
|
5731
|
+
else {
|
|
5732
|
+
throw new Error('Failed to delete RelationshipConfig from Amplify');
|
|
5733
|
+
}
|
|
5734
|
+
}
|
|
5735
|
+
catch (error) {
|
|
5736
|
+
console.error('ConfigurationsComponent: Error deleting relationship config:', error);
|
|
5737
|
+
this.snackBar.open('Error deleting configuration: ' + error, 'Dismiss', { duration: 5000 });
|
|
5601
5738
|
}
|
|
5602
5739
|
}
|
|
5603
5740
|
generateId() {
|
|
@@ -5609,11 +5746,10 @@ return fields;
|
|
|
5609
5746
|
this.relationshipConfigForm.reset();
|
|
5610
5747
|
this.availableFields = [];
|
|
5611
5748
|
}
|
|
5612
|
-
loadDefaultRelationshipConfigs() {
|
|
5749
|
+
async loadDefaultRelationshipConfigs() {
|
|
5613
5750
|
// Load some sensible default configurations
|
|
5614
5751
|
const defaultConfigs = [
|
|
5615
5752
|
{
|
|
5616
|
-
id: this.generateId(),
|
|
5617
5753
|
relationshipModel: 'ListView',
|
|
5618
5754
|
fieldName: 'table',
|
|
5619
5755
|
selectionSet: [
|
|
@@ -5627,7 +5763,6 @@ return fields;
|
|
|
5627
5763
|
description: 'Configuration for ListView -> Table relationship'
|
|
5628
5764
|
},
|
|
5629
5765
|
{
|
|
5630
|
-
id: this.generateId(),
|
|
5631
5766
|
relationshipModel: 'FormViewField',
|
|
5632
5767
|
fieldName: 'formView',
|
|
5633
5768
|
selectionSet: [
|
|
@@ -5641,7 +5776,6 @@ return fields;
|
|
|
5641
5776
|
description: 'Configuration for FormViewField -> FormView relationship'
|
|
5642
5777
|
},
|
|
5643
5778
|
{
|
|
5644
|
-
id: this.generateId(),
|
|
5645
5779
|
relationshipModel: 'ServiceCustomer',
|
|
5646
5780
|
fieldName: 'service',
|
|
5647
5781
|
selectionSet: [
|
|
@@ -5655,7 +5789,6 @@ return fields;
|
|
|
5655
5789
|
description: 'Configuration for ServiceCustomer -> Service relationship'
|
|
5656
5790
|
},
|
|
5657
5791
|
{
|
|
5658
|
-
id: this.generateId(),
|
|
5659
5792
|
relationshipModel: 'ServiceCustomer',
|
|
5660
5793
|
fieldName: 'customer',
|
|
5661
5794
|
selectionSet: [
|
|
@@ -5668,32 +5801,53 @@ return fields;
|
|
|
5668
5801
|
description: 'Configuration for ServiceCustomer -> Customer relationship'
|
|
5669
5802
|
}
|
|
5670
5803
|
];
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
c.
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5804
|
+
try {
|
|
5805
|
+
// Only add configs that don't already exist
|
|
5806
|
+
let addedCount = 0;
|
|
5807
|
+
for (const defaultConfig of defaultConfigs) {
|
|
5808
|
+
const existing = this.relationshipConfigs.find(c => c.relationshipModel === defaultConfig.relationshipModel &&
|
|
5809
|
+
c.fieldName === defaultConfig.fieldName);
|
|
5810
|
+
if (!existing) {
|
|
5811
|
+
await this.createRelationshipConfig(defaultConfig);
|
|
5812
|
+
addedCount++;
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
if (addedCount > 0) {
|
|
5816
|
+
this.snackBar.open(`Added ${addedCount} default relationship configurations`, 'Dismiss', { duration: 3000 });
|
|
5817
|
+
}
|
|
5818
|
+
else {
|
|
5819
|
+
this.snackBar.open('All default configurations already exist', 'Dismiss', { duration: 3000 });
|
|
5679
5820
|
}
|
|
5680
5821
|
}
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
this.snackBar.open(
|
|
5684
|
-
}
|
|
5685
|
-
else {
|
|
5686
|
-
this.snackBar.open('All default configurations already exist', 'Dismiss', { duration: 3000 });
|
|
5822
|
+
catch (error) {
|
|
5823
|
+
console.error('ConfigurationsComponent: Error loading default relationship configs:', error);
|
|
5824
|
+
this.snackBar.open('Error loading default configurations: ' + error, 'Dismiss', { duration: 5000 });
|
|
5687
5825
|
}
|
|
5688
5826
|
}
|
|
5689
|
-
clearAllRelationshipConfigs() {
|
|
5827
|
+
async clearAllRelationshipConfigs() {
|
|
5690
5828
|
if (this.relationshipConfigs.length === 0) {
|
|
5691
5829
|
this.snackBar.open('No relationship configurations to clear', 'Dismiss', { duration: 3000 });
|
|
5692
5830
|
return;
|
|
5693
5831
|
}
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5832
|
+
try {
|
|
5833
|
+
if (!this.hasRelationshipConfig) {
|
|
5834
|
+
// Fallback to localStorage if model not available
|
|
5835
|
+
this.relationshipConfigs = [];
|
|
5836
|
+
this.saveRelationshipConfigsToStorage();
|
|
5837
|
+
this.snackBar.open('All relationship configurations cleared', 'Dismiss', { duration: 3000 });
|
|
5838
|
+
return;
|
|
5839
|
+
}
|
|
5840
|
+
// Delete all configurations from Amplify
|
|
5841
|
+
const deletePromises = this.relationshipConfigs.map(config => this.ams.deleteItemForModel('RelationshipConfig', config.id));
|
|
5842
|
+
await Promise.all(deletePromises);
|
|
5843
|
+
// Reload configurations to get the updated (empty) list
|
|
5844
|
+
this.loadRelationshipConfigs();
|
|
5845
|
+
this.snackBar.open('All relationship configurations cleared', 'Dismiss', { duration: 3000 });
|
|
5846
|
+
}
|
|
5847
|
+
catch (error) {
|
|
5848
|
+
console.error('ConfigurationsComponent: Error clearing relationship configs:', error);
|
|
5849
|
+
this.snackBar.open('Error clearing configurations: ' + error, 'Dismiss', { duration: 5000 });
|
|
5850
|
+
}
|
|
5697
5851
|
}
|
|
5698
5852
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfigurationsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5699
5853
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfigurationsComponent, isStandalone: true, selector: "snteam-configurations", inputs: { amplifyOutputs: "amplifyOutputs" }, ngImport: i0, template: "<div class=\"configurations-container\">\n <h2>System Configurations</h2>\n \n <mat-accordion multi=\"true\">\n \n <!-- Table Configs Section -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>table_chart</mat-icon>\n <span class=\"panel-title\">Table Configs</span>\n </mat-panel-title>\n <mat-panel-description>\n Manage table configurations and settings\n </mat-panel-description>\n </mat-expansion-panel-header>\n \n <div class=\"panel-content\">\n @if (hasTableConfig) {\n <div class=\"section-actions\">\n <button mat-raised-button color=\"accent\" (click)=\"populateDefaultTableConfigs()\" class=\"populate-button\">\n <mat-icon>auto_fix_high</mat-icon>\n Populate Default Table Configs\n </button>\n <button mat-raised-button color=\"warn\" (click)=\"deleteTableConfigs()\" class=\"delete-button\">\n <mat-icon>delete</mat-icon>\n Delete All Table Configs\n </button>\n </div>\n <snteam-list-view \n [modelName]=\"'TableConfig'\"\n [useRouter]=\"true\"\n [showDeleteAction]=\"true\">\n </snteam-list-view>\n } @else {\n <mat-card class=\"error-card\">\n <mat-card-content>\n <mat-icon class=\"error-icon\">error_outline</mat-icon>\n <h3>TableConfig Model Not Found</h3>\n <p>The TableConfig model is not available in your Amplify schema. Please add it to your data model to manage table configurations.</p>\n <button mat-raised-button color=\"primary\" class=\"help-button\">\n <mat-icon>help</mat-icon>\n View Documentation\n </button>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-expansion-panel>\n\n <!-- Form Views Section -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>dynamic_form</mat-icon>\n <span class=\"panel-title\">Form Views</span>\n </mat-panel-title>\n <mat-panel-description>\n Configure custom form layouts and field selections\n </mat-panel-description>\n </mat-expansion-panel-header>\n \n <div class=\"panel-content\">\n @if (hasFormView) {\n <div class=\"section-actions\">\n <button mat-raised-button color=\"warn\" (click)=\"deleteFormViews()\" class=\"delete-button\">\n <mat-icon>delete</mat-icon>\n Delete All Form Views\n </button>\n </div>\n <snteam-list-view \n [modelName]=\"'FormView'\"\n [useRouter]=\"true\"\n [showDeleteAction]=\"true\">\n </snteam-list-view>\n } @else {\n <mat-card class=\"error-card\">\n <mat-card-content>\n <mat-icon class=\"error-icon\">error_outline</mat-icon>\n <h3>FormView Model Not Found</h3>\n <p>The FormView model is not available in your Amplify schema. Please add it to your data model to create custom form configurations.</p>\n <button mat-raised-button color=\"primary\" class=\"help-button\">\n <mat-icon>help</mat-icon>\n View Documentation\n </button>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-expansion-panel>\n\n <!-- List Views Section -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>view_list</mat-icon>\n <span class=\"panel-title\">List Views</span>\n </mat-panel-title>\n <mat-panel-description>\n Customize list displays and column configurations\n </mat-panel-description>\n </mat-expansion-panel-header>\n \n <div class=\"panel-content\">\n @if (hasListView) {\n <div class=\"section-actions\">\n <button mat-raised-button color=\"warn\" (click)=\"deleteListViews()\" class=\"delete-button\">\n <mat-icon>delete</mat-icon>\n Delete All List Views\n </button>\n </div>\n <snteam-list-view \n [modelName]=\"'ListView'\"\n [useRouter]=\"true\"\n [showDeleteAction]=\"true\">\n </snteam-list-view>\n } @else {\n <mat-card class=\"error-card\">\n <mat-card-content>\n <mat-icon class=\"error-icon\">error_outline</mat-icon>\n <h3>ListView Model Not Found</h3>\n <p>The ListView model is not available in your Amplify schema. Please add it to your data model to create custom list view configurations.</p>\n <button mat-raised-button color=\"primary\" class=\"help-button\">\n <mat-icon>help</mat-icon>\n View Documentation\n </button>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-expansion-panel>\n\n <!-- Field Configs Section -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>settings</mat-icon>\n <span class=\"panel-title\">Field Configs</span>\n </mat-panel-title>\n <mat-panel-description>\n Configure field behavior, validation, and choices\n </mat-panel-description>\n </mat-expansion-panel-header>\n \n <div class=\"panel-content\">\n @if (hasFieldConfig) {\n <div class=\"section-actions\">\n <button mat-raised-button color=\"accent\" (click)=\"populateDefaultFieldConfigs()\" class=\"populate-button\">\n <mat-icon>auto_fix_high</mat-icon>\n Populate Default Field Configs\n </button>\n <button mat-raised-button color=\"warn\" (click)=\"deleteFieldConfigs()\" class=\"delete-button\">\n <mat-icon>delete</mat-icon>\n Delete All Field Configs\n </button>\n </div>\n <snteam-list-view \n [modelName]=\"'FieldConfig'\"\n [useRouter]=\"true\"\n [showDeleteAction]=\"true\">\n </snteam-list-view>\n } @else {\n <mat-card class=\"error-card\">\n <mat-card-content>\n <mat-icon class=\"error-icon\">error_outline</mat-icon>\n <h3>FieldConfig Model Not Found</h3>\n <p>The FieldConfig model is not available in your Amplify schema. Please add it to your data model to configure field behavior and validation.</p>\n <button mat-raised-button color=\"primary\" class=\"help-button\">\n <mat-icon>help</mat-icon>\n View Documentation\n </button>\n </mat-card-content>\n </mat-card>\n }\n </div>\n </mat-expansion-panel>\n\n <!-- Relationship Configs Section -->\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-icon>link</mat-icon>\n <span class=\"panel-title\">Relationship Configs</span>\n </mat-panel-title>\n <mat-panel-description>\n Configure GraphQL selection sets for relationship queries\n </mat-panel-description>\n </mat-expansion-panel-header>\n \n <div class=\"panel-content\">\n <div class=\"section-actions\">\n <button mat-raised-button color=\"primary\" (click)=\"showAddRelationshipConfig = !showAddRelationshipConfig\" class=\"add-button\">\n <mat-icon>{{ showAddRelationshipConfig ? 'close' : 'add' }}</mat-icon>\n {{ showAddRelationshipConfig ? 'Cancel' : 'Add Relationship Config' }}\n </button>\n <button mat-raised-button color=\"accent\" (click)=\"loadDefaultRelationshipConfigs()\" class=\"populate-button\">\n <mat-icon>auto_fix_high</mat-icon>\n Load Default Configs\n </button>\n <button mat-raised-button color=\"warn\" (click)=\"clearAllRelationshipConfigs()\" class=\"delete-button\">\n <mat-icon>delete</mat-icon>\n Clear All Configs\n </button>\n </div>\n\n <!-- Add/Edit Relationship Config Form -->\n @if (showAddRelationshipConfig) {\n <mat-card class=\"config-form-card\">\n <mat-card-header>\n <mat-card-title>\n <mat-icon>{{ editingRelationshipConfig ? 'edit' : 'add' }}</mat-icon>\n {{ editingRelationshipConfig ? 'Edit' : 'Add' }} Relationship Configuration\n </mat-card-title>\n </mat-card-header>\n <mat-card-content>\n <form [formGroup]=\"relationshipConfigForm\" (ngSubmit)=\"saveRelationshipConfig()\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Relationship Model</mat-label>\n <mat-select formControlName=\"relationshipModel\" (selectionChange)=\"onRelationshipModelChange($event)\">\n @for (model of availableModels; track model) {\n <mat-option [value]=\"model\">{{ model }}</mat-option>\n }\n </mat-select>\n <mat-hint>The model that contains the relationship field</mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Field Name</mat-label>\n <mat-select formControlName=\"fieldName\">\n @for (field of availableFields; track field.name) {\n <mat-option [value]=\"field.name\">{{ field.label }}</mat-option>\n }\n </mat-select>\n <mat-hint>The relationship field in the selected model</mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Selection Set</mat-label>\n <textarea \n matInput \n formControlName=\"selectionSet\" \n rows=\"6\"\n placeholder=\"Enter GraphQL selection fields, one per line: id table table.id table.name table.title\">\n </textarea>\n <mat-hint>GraphQL fields to select for this relationship (one per line)</mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"form-row\">\n <mat-form-field appearance=\"outline\" class=\"full-width\">\n <mat-label>Description</mat-label>\n <input matInput formControlName=\"description\" placeholder=\"Optional description for this configuration\">\n <mat-hint>Optional description to document this configuration</mat-hint>\n </mat-form-field>\n </div>\n\n <div class=\"form-actions\">\n <button mat-raised-button color=\"primary\" type=\"submit\" [disabled]=\"!relationshipConfigForm.valid\">\n <mat-icon>save</mat-icon>\n {{ editingRelationshipConfig ? 'Update' : 'Save' }} Configuration\n </button>\n <button mat-button type=\"button\" (click)=\"cancelRelationshipConfigEdit()\">\n <mat-icon>cancel</mat-icon>\n Cancel\n </button>\n </div>\n </form>\n </mat-card-content>\n </mat-card>\n }\n\n <!-- Current Relationship Configurations -->\n <div class=\"current-configs\">\n <h3>Current Relationship Configurations</h3>\n @if (relationshipConfigs.length === 0) {\n <mat-card class=\"empty-state-card\">\n <mat-card-content>\n <mat-icon class=\"empty-icon\">link_off</mat-icon>\n <h4>No Relationship Configurations</h4>\n <p>Add relationship configurations to control GraphQL selection sets for relationship queries.</p>\n </mat-card-content>\n </mat-card>\n } @else {\n <div class=\"configs-list\">\n @for (config of relationshipConfigs; track config.id) {\n <mat-card class=\"config-card\">\n <mat-card-header>\n <mat-card-title>{{ config.relationshipModel }} \u2192 {{ config.fieldName }}</mat-card-title>\n <mat-card-subtitle>{{ config.description || 'No description' }}</mat-card-subtitle>\n <div class=\"card-actions\">\n <button mat-icon-button (click)=\"editRelationshipConfig(config)\" matTooltip=\"Edit Configuration\">\n <mat-icon>edit</mat-icon>\n </button>\n <button mat-icon-button color=\"warn\" (click)=\"deleteRelationshipConfig(config)\" matTooltip=\"Delete Configuration\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </mat-card-header>\n <mat-card-content>\n <div class=\"selection-set\">\n <strong>Selection Set:</strong>\n <div class=\"selection-fields\">\n @for (field of config.selectionSet; track field) {\n <span class=\"field-chip\">{{ field }}</span>\n }\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n }\n </div>\n }\n </div>\n\n <!-- Configuration Status -->\n <div class=\"config-status\">\n <mat-card class=\"status-card\">\n <mat-card-content>\n <div class=\"status-info\">\n <mat-icon class=\"status-icon\">info</mat-icon>\n <div class=\"status-text\">\n <strong>Active Configurations: {{ relationshipConfigs.length }}</strong>\n <p>These configurations control how relationship data is queried from your GraphQL API.</p>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </div>\n </mat-expansion-panel>\n\n </mat-accordion>\n</div>", styles: [".configurations-container{padding:20px;max-width:1200px;margin:0 auto}.configurations-container h2{margin-bottom:24px;color:#333;font-weight:500}.mat-expansion-panel{margin-bottom:16px;border-radius:8px;box-shadow:0 2px 4px #0000001a}.mat-expansion-panel-header{padding:16px 24px}.panel-title{margin-left:12px;font-weight:500;font-size:16px}.mat-panel-description{color:#666;font-size:14px}.panel-content{padding:16px 24px 24px;background-color:#fafafa}.error-card{text-align:center;padding:24px;background-color:#fff;border:2px dashed #ddd;border-radius:8px}.error-card mat-card-content{padding:0}.error-icon{font-size:48px;width:48px;height:48px;color:#ff9800;margin-bottom:16px}.error-card h3{margin:0 0 12px;color:#333;font-weight:500}.error-card p{color:#666;line-height:1.5;max-width:500px;margin:0 auto 20px}.help-button{margin-top:8px}.help-button mat-icon{margin-right:8px}.section-actions{margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #e0e0e0;display:flex;gap:12px;flex-wrap:wrap}.generate-button{background-color:#2196f3;color:#fff}.generate-button mat-icon{margin-right:8px}.delete-button{background-color:#f44336;color:#fff}.delete-button mat-icon{margin-right:8px}.populate-button mat-icon{margin-right:8px}@media (max-width: 768px){.configurations-container{padding:16px}.panel-content{padding:12px 16px 16px}.error-card{padding:16px}.error-icon{font-size:36px;width:36px;height:36px}}.add-button{background-color:#4caf50;color:#fff}.add-button mat-icon{margin-right:8px}.config-form-card{margin:16px 0;background-color:#fff;border-radius:8px;box-shadow:0 2px 8px #0000001a}.config-form-card mat-card-header{background-color:#f5f5f5;border-radius:8px 8px 0 0;padding:16px 24px}.config-form-card mat-card-title{display:flex;align-items:center;font-size:18px;font-weight:500;color:#333}.config-form-card mat-card-title mat-icon{margin-right:12px;color:#2196f3}.config-form-card mat-card-content{padding:24px}.form-row{margin-bottom:20px}.full-width{width:100%}.form-actions{display:flex;gap:12px;margin-top:24px;padding-top:16px;border-top:1px solid #e0e0e0}.form-actions button mat-icon{margin-right:8px}.current-configs{margin-top:24px}.current-configs h3{margin-bottom:16px;color:#333;font-weight:500}.empty-state-card{text-align:center;padding:32px;background-color:#fff;border:2px dashed #ddd;border-radius:8px}.empty-state-card mat-card-content{padding:0}.empty-icon{font-size:48px;width:48px;height:48px;color:#bbb;margin-bottom:16px}.empty-state-card h4{margin:0 0 12px;color:#333;font-weight:500}.empty-state-card p{margin:0;color:#666;line-height:1.5}.configs-list{display:grid;gap:16px}.config-card{background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;transition:box-shadow .2s ease}.config-card:hover{box-shadow:0 4px 8px #00000026}.config-card mat-card-header{padding:16px 20px;border-bottom:1px solid #f0f0f0;display:flex;align-items:center;justify-content:space-between}.config-card mat-card-title{font-size:16px;font-weight:500;color:#333;margin:0}.config-card mat-card-subtitle{font-size:14px;color:#666;margin:4px 0 0}.card-actions{display:flex;gap:4px}.config-card mat-card-content{padding:16px 20px}.selection-set{margin:0}.selection-set strong{display:block;margin-bottom:8px;color:#333;font-size:14px}.selection-fields{display:flex;flex-wrap:wrap;gap:6px}.field-chip{display:inline-block;padding:4px 8px;background-color:#e3f2fd;color:#1976d2;border-radius:12px;font-size:12px;font-family:Roboto Mono,monospace;border:1px solid #bbdefb}.config-status{margin-top:24px}.status-card{background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.status-card mat-card-content{padding:16px 20px}.status-info{display:flex;align-items:flex-start;gap:12px}.status-icon{color:#2196f3;margin-top:2px}.status-text strong{display:block;margin-bottom:4px;color:#333;font-size:16px}.status-text p{margin:0;color:#666;font-size:14px;line-height:1.5}@media (max-width: 768px){.config-form-card mat-card-content{padding:16px}.form-actions{flex-direction:column}.form-actions button{width:100%}.config-card mat-card-header{flex-direction:column;align-items:flex-start;gap:8px}.card-actions{align-self:flex-end}.selection-fields{gap:4px}.field-chip{font-size:11px;padding:3px 6px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i2.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i2.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i2.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i2.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i4$2.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4$2.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i4$2.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i4$2.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i4$2.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3$3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "component", type: ListViewComponent, selector: "snteam-list-view", inputs: ["modelName", "customItemTemplate", "hideNewButton", "title", "useRouter", "showRowActions", "showDeleteAction", "customRowActions"], outputs: ["itemClick", "newClick", "itemsLoaded", "itemDeleted"] }] });
|