Skip to content

Commit 7643c43

Browse files
jessewashburnMutugiiidogi
authored
community: smoother services linking (fixes #9084) (#9090)
Co-authored-by: mutugiii <[email protected]> Co-authored-by: dogi <[email protected]>
1 parent 04e6c9f commit 7643c43

16 files changed

+125
-17
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "planet",
33
"license": "AGPL-3.0",
4-
"version": "0.20.60",
4+
"version": "0.20.61",
55
"myplanet": {
6-
"latest": "v0.36.9",
7-
"min": "v0.35.9"
6+
"latest": "v0.36.25",
7+
"min": "v0.35.25"
88
},
99
"scripts": {
1010
"ng": "ng",

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: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,24 @@
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>

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/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/teams/teams.service.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export class TeamsService {
365365
return `/${mode}s/view/${teamId}`;
366366
}
367367

368-
createServicesLink({ title, route, teamType }) {
368+
createServicesLink({ title, route, teamType, icon }) {
369369
const { code, parentCode } = this.stateService.configuration;
370370
const newServicesDoc = {
371371
'teamId': `${code}@${parentCode}`,
@@ -374,6 +374,7 @@ export class TeamsService {
374374
'parentCode': `${parentCode}`,
375375
'docType': 'link',
376376
teamType,
377+
icon,
377378
title,
378379
route
379380
};

src/assets/icons/discord.svg

Lines changed: 1 addition & 0 deletions
Loading

src/assets/icons/facebook.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)