Skip to content

Commit ff827fd

Browse files
authored
Merge branch 'master' into codex/remove-unused-exports-from-utils.ts
2 parents 83c18be + 9ffae30 commit ff827fd

29 files changed

Lines changed: 258 additions & 115 deletions

git-hooks/pre-push

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,6 @@
33
# An example hook script to verify what is about to be pushed. Called by "git
44
# push" after it has checked the remote status, but before anything has been
55
# pushed. If this script exits with a non-zero status nothing will be pushed.
6-
#
7-
# This hook is called with the following parameters:
8-
#
9-
# $1 -- Name of the remote to which the push is being done
10-
# $2 -- URL to which the push is being done
11-
#
12-
# If pushing without using a named remote those arguments will be equal.
13-
#
14-
# Information about the commits which are being pushed is supplied as lines to
15-
# the standard input in the form:
16-
#
17-
# <local ref> <local sha1> <remote ref> <remote sha1>
18-
#
19-
# This sample shows how to prevent push of commits where the log message starts
20-
# with "WIP" (work in progress).
21-
22-
remote="$1"
23-
url="$2"
246

257
pass=true
268
RED='\033[1;31m'

src/app/app.component.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ export class AppComponent {
2525
iconRegistry.addSvgIcon(
2626
'myLife',
2727
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/selfimprovement.svg'));
28-
iconRegistry.addSvgIcon(
29-
'myTeams',
30-
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/group.svg'));
3128
iconRegistry.addSvgIcon(
3229
'feedback',
3330
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/feedback.svg'));
@@ -58,6 +55,27 @@ export class AppComponent {
5855
iconRegistry.addSvgIcon(
5956
'unpin',
6057
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/unpin.svg'));
58+
iconRegistry.addSvgIcon(
59+
'instagram',
60+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/instagram.svg'));
61+
iconRegistry.addSvgIcon(
62+
'facebook',
63+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/facebook.svg'));
64+
iconRegistry.addSvgIcon(
65+
'whatsapp',
66+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/whatsapp.svg'));
67+
iconRegistry.addSvgIcon(
68+
'discord',
69+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/discord.svg'));
70+
iconRegistry.addSvgIcon(
71+
'x',
72+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/x.svg'));
73+
iconRegistry.addSvgIcon(
74+
'youtube',
75+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/youtube.svg'));
76+
iconRegistry.addSvgIcon(
77+
'tiktok',
78+
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/tiktok.svg'));
6179

6280
this.router.events.subscribe(event => {
6381
if (event instanceof NavigationStart) {

src/app/community/community-link-dialog.component.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,40 @@
2121
</mat-horizontal-stepper>
2222
</form>
2323
</mat-dialog-content>
24+
<mat-dialog-content *ngIf="selectedLink?.db === 'social'">
25+
<form [formGroup]="linkForm">
26+
<mat-form-field class="full-width">
27+
<mat-label i18n>Platform</mat-label>
28+
<mat-select formControlName="platform" (selectionChange)="onPlatformSelect($event.value)" required>
29+
<mat-select-trigger>
30+
<ng-container [ngSwitch]="linkForm.value.platform">
31+
<mat-icon *ngSwitchCase="'website'" class="margin-r-5">public</mat-icon>
32+
<mat-icon *ngSwitchDefault [svgIcon]="linkForm.value.platform" class="margin-r-5"></mat-icon>
33+
</ng-container>
34+
{{getPlatformLabel(linkForm.value.platform)}}
35+
</mat-select-trigger>
36+
<mat-option *ngFor="let p of socialPlatforms" [value]="p.value">
37+
<ng-container [ngSwitch]="p.value">
38+
<mat-icon *ngSwitchCase="'website'" class="margin-r-5">public</mat-icon>
39+
<mat-icon *ngSwitchDefault [svgIcon]="p.value" class="margin-r-5"></mat-icon>
40+
</ng-container>
41+
{{ p.label }}
42+
</mat-option>
43+
</mat-select>
44+
<mat-error *ngIf="linkForm.controls.platform.invalid && linkForm.controls.platform.touched" i18n>Platform is required.</mat-error>
45+
</mat-form-field>
46+
<mat-form-field class="full-width">
47+
<mat-label i18n>Title</mat-label>
48+
<input matInput formControlName="title" required>
49+
<mat-error><planet-form-error-messages [control]="linkForm.controls.title"></planet-form-error-messages></mat-error>
50+
</mat-form-field>
51+
<mat-form-field class="full-width">
52+
<mat-label i18n>Link URL</mat-label>
53+
<input matInput formControlName="route" placeholder="https://..." required>
54+
<mat-error><planet-form-error-messages [control]="linkForm.controls.route"></planet-form-error-messages></mat-error>
55+
</mat-form-field>
56+
</form>
57+
</mat-dialog-content>
2458
<mat-dialog-actions>
2559
<button type="button" mat-raised-button (click)="cancelForm()" i18n>Cancel</button>
2660
<button mat-raised-button color="primary" type="button" (click)="linkSubmit()" [disabled]="!linkForm.valid" i18n>OK</button>

src/app/community/community-link-dialog.component.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@ export class CommunityLinkDialogComponent {
1717
selectedLink: { db, title, selector? };
1818
links: { db, title, selector? }[] = [
1919
{ db: 'teams', title: $localize`Teams`, selector: { type: 'team' } },
20-
{ db: 'teams', title: $localize`Enterprises`, selector: { type: 'enterprise' } }
20+
{ db: 'teams', title: $localize`Enterprises`, selector: { type: 'enterprise' } },
21+
{ db: 'social', title: $localize`Web & Social` }
2122
];
2223
linkForm: UntypedFormGroup;
24+
socialPlatforms = [
25+
{ value: 'instagram', label: 'Instagram' },
26+
{ value: 'facebook', label: 'Facebook' },
27+
{ value: 'whatsapp', label: 'WhatsApp' },
28+
{ value: 'discord', label: 'Discord' },
29+
{ value: 'x', label: 'X (Twitter)' },
30+
{ value: 'youtube', label: 'YouTube' },
31+
{ value: 'tiktok', label: 'TikTok' },
32+
{ value: 'website', label: 'Website' }
33+
];
2334

2435
constructor(
2536
private dialogRef: MatDialogRef<CommunityLinkDialogComponent>,
@@ -33,14 +44,17 @@ export class CommunityLinkDialogComponent {
3344
title: [ '', CustomValidators.required, ac => this.validatorService.isUnique$('teams', 'title', ac, {}) ],
3445
route: [ '', CustomValidators.required ],
3546
linkId: '',
36-
teamType: ''
47+
teamType: '',
48+
icon: '',
49+
platform: ''
3750
});
3851
}
3952

4053
teamSelect({ mode, teamId, teamType }) {
4154
this.linkForm.controls.route.setValue(this.teamsService.teamLinkRoute(mode, teamId));
4255
this.linkForm.controls.linkId.setValue(teamId);
4356
this.linkForm.controls.teamType.setValue(teamType);
57+
this.linkForm.controls.icon.setValue(mode === 'team' ? 'groups' : 'work');
4458
this.linkStepper.selected.completed = true;
4559
this.linkStepper.next();
4660
}
@@ -69,4 +83,18 @@ export class CommunityLinkDialogComponent {
6983
cancelForm() {
7084
this.dialogRef.close();
7185
}
86+
87+
onPlatformSelect(platform: string) {
88+
this.linkForm.controls.icon.setValue(this.socialPlatforms.find(p => p.value === platform)?.value || '');
89+
this.linkForm.controls.teamType.setValue('social');
90+
91+
// Apply URL validator for generic Website entries
92+
const routeCtrl = this.linkForm.controls.route;
93+
routeCtrl.setAsyncValidators(platform === 'website' ? [CustomValidators.validLink] : []);
94+
routeCtrl.updateValueAndValidity();
95+
}
96+
97+
getPlatformLabel(platform: string): string {
98+
return this.socialPlatforms.find(p => p.value === platform)?.label || '';
99+
}
72100
}

src/app/community/community.component.html

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,36 @@
7878
<ng-container>
7979
<b i18n>{ configuration.planetType, select, community {Community} nation {Nation} center {Earth}} Links</b>
8080
<span *ngIf="links?.length === 0" i18n><p>No links available.</p></span>
81-
<mat-nav-list>
82-
<mat-list-item *ngFor="let link of links" [routerLink]="(link.teamType === 'sync' || !planetCode) ? link.route : []" i18n-matTooltip [matTooltip]="(link.teamType === 'sync' || !planetCode) ? '' : link.title + ' is only available on ' + configuration.name" [disableRipple]="link.teamType === 'local' && planetCode">
83-
<span matLine>{{link.title}}</span>
84-
<button *ngIf="deleteMode" mat-icon-button color="warn" (click)="openDeleteLinkDialog(link); $event.stopPropagation()"><mat-icon>delete</mat-icon></button>
85-
</mat-list-item>
81+
<mat-nav-list *ngIf="links?.length > 0">
82+
<ng-container *ngIf="localLinks.length > 0">
83+
<h3 mat-subheader i18n>Local</h3>
84+
<mat-list-item *ngFor="let link of localLinks" [routerLink]="(link.teamType === 'sync' || !planetCode) ? link.route : []" i18n-matTooltip [matTooltip]="(link.teamType === 'sync' || !planetCode) ? '' : link.title + ' is only available on ' + configuration.name" [disableRipple]="link.teamType === 'local' && planetCode">
85+
<mat-icon matListIcon>{{link.icon || 'link'}}</mat-icon>
86+
<span matLine>{{link.title}}</span>
87+
<button *ngIf="deleteMode" mat-icon-button color="warn" (click)="openDeleteLinkDialog(link); $event.stopPropagation()"><mat-icon>delete</mat-icon></button>
88+
</mat-list-item>
89+
</ng-container>
90+
<ng-container *ngIf="socialWebLinks.length > 0">
91+
<h3 mat-subheader i18n>Social & Web</h3>
92+
<a *ngFor="let link of socialWebLinks" mat-list-item [href]="link.route" target="_blank" rel="noopener">
93+
<mat-icon *ngIf="link.icon === 'web'" matListIcon>public</mat-icon>
94+
<mat-icon *ngIf="link.icon !== 'web'" [svgIcon]="link.icon" matListIcon></mat-icon>
95+
<span matLine>{{link.title}}</span>
96+
<button *ngIf="deleteMode" mat-icon-button color="warn" (click)="openDeleteLinkDialog(link); $event.preventDefault(); $event.stopPropagation()"><mat-icon>delete</mat-icon></button>
97+
</a>
98+
</ng-container>
8699
</mat-nav-list>
87100
</ng-container>
88101
<ng-template #noLinks>
89102
<p i18n>No links available.</p>
90103
</ng-template>
91-
<ng-container *planetAuthorizedRoles="''">
104+
<div *planetAuthorizedRoles="''" class="action-buttons">
92105
<button (click)="openAddLinkDialog()" mat-stroked-button i18n>Add Link</button>
93106
<button (click)="toggleDeleteMode()" [disabled]="links.length===0" mat-stroked-button>
94107
<span *ngIf="!deleteMode" i18n>Remove Links</span>
95108
<span *ngIf="deleteMode" i18n>Done Removing Links</span>
96109
</button>
97-
</ng-container>
110+
</div>
98111
</mat-tab>
99112
<mat-tab *ngIf="configuration.planetType==='nation' && isLoggedIn" i18n-label label="Communities">
100113
<planet-community-list></planet-community-list>

src/app/community/community.component.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ export class CommunityComponent implements OnInit, OnDestroy {
7171
pinned = false;
7272
attachmentMap: Record<string, any> = {};
7373

74+
get localLinks(): any[] {
75+
return (this.links || []).filter(link => link.teamType !== 'social');
76+
}
77+
78+
get socialWebLinks(): any[] {
79+
return (this.links || []).filter(link => link.teamType === 'social');
80+
}
81+
7482
get leadersTabLabel(): string {
7583
return this.configuration.planetType === 'nation' ? $localize`Nation Leaders` : $localize`Community Leaders`;
7684
}
@@ -307,7 +315,7 @@ export class CommunityComponent implements OnInit, OnDestroy {
307315
this.deleteMode = this.deleteMode && this.links.length !== 0;
308316
this.finances = finances;
309317
this.reports = reports;
310-
this.financesLoading = false;
318+
this.financesLoading = false;
311319
}
312320

313321
dataChanged() {

src/app/community/community.scss

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@
1414
grid-template-columns: 1fr;
1515
grid-template-areas: "news";
1616
}
17+
18+
.toggle-button {
19+
margin-bottom: 1rem;
20+
}
21+
22+
.action-buttons {
23+
button {
24+
margin-top: 0.5rem;
25+
}
26+
}
27+
28+
.responsive-toolbar {
29+
border-radius: 7.5px;
30+
}
31+
32+
.label-icon {
33+
vertical-align: middle;
34+
margin-right: 4px;
35+
}
1736
}
1837

1938
.community-news {
@@ -60,14 +79,6 @@ mat-tab-group, mat-tab {
6079
padding-top: 0.5rem;
6180
}
6281

63-
.toggle-button {
64-
margin-bottom: 1rem;
65-
}
66-
67-
.community-view .responsive-toolbar {
68-
border-radius: 7.5px;
69-
}
70-
7182
.toolbar-row {
7283
display: flex;
7384
flex-wrap: wrap;
@@ -94,11 +105,6 @@ mat-tab-group, mat-tab {
94105
}
95106
}
96107

97-
.label-icon {
98-
vertical-align: middle;
99-
margin-right: 4px;
100-
}
101-
102108
@media only screen and (max-width: $screen-sm) {
103109
.community-view .responsive-toolbar {
104110
height: auto;

src/app/courses/search-courses/courses-search.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class CoursesSearchListComponent {
4949
}
5050

5151
isSelected(item) {
52-
return this.selected.indexOf(item) > -1;
52+
return this.selected.indexOf(item.value) > -1;
5353
}
5454

5555
}

src/app/home/home.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ <h1><ng-container>Planet</ng-container> {{planetName}}</h1>
174174
routerLinkActive="active"
175175
planetPulsateIcon
176176
i18n-title title="Teams">
177-
<mat-icon svgIcon="myTeams"></mat-icon>
177+
<mat-icon>groups</mat-icon>
178178
<label i18n>Teams</label>
179179
</a>
180180
</li>

src/app/manager-dashboard/manager-aiservices.component.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@
22
<button mat-icon-button routerLink="/manager">
33
<mat-icon>arrow_back</mat-icon>
44
</button>
5-
<span i18n>AI API Configurations</span>
5+
<span i18n>AI Configurations</span>
66
</mat-toolbar>
77

88
<form class="container" [formGroup]="configForm">
99
<mat-card class="card">
1010
<mat-card-title i18n>API Keys</mat-card-title>
1111
<mat-card-content *ngIf="configuration.keys">
1212
<mat-list>
13-
<mat-list-item *ngFor="let key of objectKeys(configuration.keys)">
13+
<mat-list-item *ngFor="let apiKey of configuration.keys | keyvalue">
1414
<div class="list-item-content">
15-
<span>{{ key | titlecase }}</span>
15+
<span>{{ apiKey.key | titlecase }}</span>
1616
<mat-form-field>
1717
<input
1818
matInput
19-
[type]="hideKey[key] ? 'password' : 'text'"
20-
[formControlName]="'keys_' + key"
19+
[type]="hideKey[apiKey.key] ? 'password' : 'text'"
20+
[formControlName]="'keys_' + apiKey.key"
2121
placeholder="Enter API key"
2222
i18n-placeholder
2323
/>
24-
<button mat-icon-button matSuffix (click)="toggleHideKey(key)">
25-
<mat-icon>{{ hideKey[key] ? 'visibility_off' : 'visibility' }}</mat-icon>
24+
<button mat-icon-button matSuffix (click)="toggleHideKey(apiKey.key)">
25+
<mat-icon>{{ hideKey[apiKey.key] ? 'visibility_off' : 'visibility' }}</mat-icon>
2626
</button>
27-
<button mat-icon-button matSuffix (click)="copyKey(key)">
27+
<button mat-icon-button matSuffix (click)="copyKey(apiKey.key)">
2828
<mat-icon>content_copy</mat-icon>
2929
</button>
3030
</mat-form-field>
@@ -39,11 +39,11 @@
3939
<mat-card-title i18n>Models</mat-card-title>
4040
<mat-card-content *ngIf="configuration.models">
4141
<mat-list>
42-
<mat-list-item *ngFor="let model of objectKeys(configuration.models)">
42+
<mat-list-item *ngFor="let model of configuration.models | keyvalue">
4343
<div class="list-item-content">
44-
<span>{{ model | titlecase }}</span>
44+
<span>{{ model.key | titlecase }}</span>
4545
<mat-form-field>
46-
<input matInput [formControlName]="'models_' + model" placeholder="Enter model" i18n-placeholder />
46+
<input matInput [formControlName]="'models_' + model.key" placeholder="Enter model" i18n-placeholder />
4747
</mat-form-field>
4848
</div>
4949
</mat-list-item>

0 commit comments

Comments
 (0)