Skip to content

Commit

Permalink
add translations module
Browse files Browse the repository at this point in the history
  • Loading branch information
khalifan-kfan committed Jan 2, 2024
1 parent 66bc218 commit e02dc68
Show file tree
Hide file tree
Showing 14 changed files with 295 additions and 13 deletions.
8 changes: 4 additions & 4 deletions apps/picsa-apps/dashboard/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ export class AppComponent implements AfterViewInit {
// label: 'Monitoring Forms',
// href: '/monitoring-forms',
// },
// {
// label: 'Translations',
// href: '/translations',
// },
{
label: 'Translations',
href: '/translations',
},
];

globalLinks: INavLink[] = [
Expand Down
4 changes: 4 additions & 0 deletions apps/picsa-apps/dashboard/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ export const appRoutes: Route[] = [
path: 'climate-data',
loadChildren: () => import('./modules/climate-data/climate-data.module').then((m) => m.ClimateDataModule),
},
{
path: 'translations',
loadChildren: () => import('./modules/translations/translations.module').then((m) => m.TranslationsPageModule),
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="page-content">
<h2>Edit Translations</h2>


</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslationsEditComponent } from './translations-edit.component';

describe('TranslationsEditComponent', () => {
let component: TranslationsEditComponent;
let fixture: ComponentFixture<TranslationsEditComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslationsEditComponent],
}).compileComponents();

fixture = TestBed.createComponent(TranslationsEditComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
// eslint-disable-next-line @nx/enforce-module-boundaries
import type { Database } from '@picsa/server-types';
import { PICSAFormValidators } from '@picsa/shared/modules/forms/validators';
//import {
// IUploadResult,
// SupabaseStoragePickerDirective,
// SupabaseUploadComponent,
// } from '@picsa/shared/services/core/supabase';
// import { IStorageEntry } from '@picsa/shared/services/core/supabase/services/supabase-storage.service';

// import { DashboardMaterialModule } from '../../../../material.module';
// import { DashboardResourcesStorageLinkComponent } from '../../components/storage-link/storage-link.component';
// import { ResourcesDashboardService } from '../../translations.service';

// type IResourceEntry = Database['public']['Tables']['resources']['Row'];

@Component({
selector: 'dashboard-resource-create',
standalone: true,
imports: [
CommonModule,
// DashboardMaterialModule,
// DashboardResourcesStorageLinkComponent,
// FormsModule,
// ReactiveFormsModule,
// SupabaseStoragePickerDirective,
// SupabaseUploadComponent,
],
templateUrl: './translations-edit.component.html',
styleUrls: ['./translations-edit.component.scss'],
})
export class TranslationsEditComponent {
constructor(
// private service: ResourcesDashboardService,
private route: ActivatedRoute
) {}







}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="page-content">
<div style="display: flex">
<h2 style="flex: 1">Translations</h2>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
table.resources-table {
max-height: 50vh;
display: block;
overflow: auto;
}
tr.resource-row {
cursor: pointer;
&:hover {
background: whitesmoke;
}
}
th {
font-weight: bold;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TranslationsPageComponent } from './translations.page';

describe('TranslationsPageComponent', () => {
let component: TranslationsPageComponent;
let fixture: ComponentFixture<TranslationsPageComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslationsPageComponent],
}).compileComponents();

fixture = TestBed.createComponent(TranslationsPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { RouterModule } from '@angular/router';

import { DashboardMaterialModule } from '../../../../material.module';
// import { DashboardResourcesStorageLinkComponent } from '../../components';
import { ResourcesDashboardService } from '../../translations.service';

@Component({
selector: 'dashboard-resources-page',
standalone: true,
imports: [CommonModule, DashboardMaterialModule, RouterModule],
templateUrl: './translations.page.html',
styleUrls: ['./translations.page.scss'],
})
export class TranslationsPageComponent implements OnInit {
//public displayedColumns = ['title', 'storage_file'];
constructor(public service: ResourcesDashboardService) {}
ngOnInit(): void {
this.service.ready();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { TranslationsEditComponent } from './pages/edit/translations-edit.component';
import { TranslationsPageComponent } from './pages/home/translations.page';

@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forChild([
{
path: '',
component: TranslationsPageComponent,
},
{
path: 'edit',
component: TranslationsEditComponent,
},
{
path: ':id',
component: TranslationsEditComponent,
},
]),
],
})
export class TranslationsPageModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Injectable, signal } from '@angular/core';
// eslint-disable-next-line @nx/enforce-module-boundaries
import { Database } from '@picsa/server-types';
import { PicsaAsyncService } from '@picsa/shared/services/asyncService.service';
import { PicsaNotificationService } from '@picsa/shared/services/core/notification.service';
import { SupabaseService } from '@picsa/shared/services/core/supabase';
import { IStorageEntry } from '@picsa/shared/services/core/supabase/services/supabase-storage.service';
import { arrayToHashmap } from '@picsa/utils';

export interface IResourceStorageEntry extends IStorageEntry {
/** Url generated when upload to public bucket (will always be populated, even if bucket not public) */
publicUrl: string;
}

export type IResourceEntry = Database['public']['Tables']['resources']['Row'];

@Injectable({ providedIn: 'root' })
export class ResourcesDashboardService extends PicsaAsyncService {
private storageFiles: IResourceStorageEntry[] = [];
public storageFilesHashmap: Record<string, IResourceStorageEntry> = {};
public readonly resources = signal<IResourceEntry[]>([]);

public get table() {
return this.supabaseService.db.table('resources');
}

constructor(private supabaseService: SupabaseService, private notificationService: PicsaNotificationService) {
super();
}

public override async init() {
await this.supabaseService.ready();
await this.listStorageFiles();
await this.listResources();
}

/** Retrieve storage db meta for a file */
public async getStorageFileById(id: string) {
// Refresh storage file cache if id not found
if (!this.storageFilesHashmap[id]) {
await this.listStorageFiles();
}
return this.storageFilesHashmap[id];
}

/**
*
* TODO - only enable super admin/local dev
* TODO - remove when no longer required
*/
public async migrateHardcodedResources() {
// NOTE - assumes storage files manually uploaded

// eslint-disable-next-line @nx/enforce-module-boundaries
const { DB_COLLECTION_ENTRIES, DB_FILE_ENTRIES, DB_LINK_ENTRIES } = await import(
'@picsa/resources/src/app/data/index'
);
console.log({ DB_COLLECTION_ENTRIES, DB_FILE_ENTRIES, DB_LINK_ENTRIES });
const ref = this.supabaseService.db.table('resources');
const uploaded: unknown[] = [];
const missing: unknown[] = [];

for (const fileEntry of Object.values(DB_FILE_ENTRIES)) {
const { type, description, url } = fileEntry;
// extract pathname from firebase url
const { pathname } = new URL(url);
const storagePath = decodeURI(pathname).replace(/%2F/g, '/').replace('/v0/b/picsa-apps.appspot.com/o/', '');
// check for equivalent storage file
const storageFile = this.storageFiles.find((file) => file.name === storagePath);
if (storageFile) {
const dbEntry: Database['public']['Tables']['resources']['Insert'] = {
description,
type,

storage_file: storageFile.id,
};
const { error } = await ref.upsert(dbEntry, { ignoreDuplicates: false });

if (error) {
console.error(error);
}
uploaded.push(fileEntry);
} else {
missing.push(fileEntry);
}
}
console.log({ uploaded, missing });
if (missing.length > 0) {
this.notificationService.showUserNotification({
matIcon: 'error',
message: `${missing.length} files missing from storage`,
});
}
}

private async listStorageFiles() {
const storageFiles = await this.supabaseService.storage.list('resources');
this.storageFiles = storageFiles.map((file) => ({
...file,
publicUrl: this.supabaseService.storage.getPublicLink(file.bucket_id as string, file.name as string),
}));
this.storageFilesHashmap = arrayToHashmap(this.storageFiles, 'id');
console.log('storage files', this.storageFilesHashmap);
}

private async listResources() {
const { data, error } = await this.supabaseService.db.table('resources').select<'*', IResourceEntry>('*');
if (error) {
throw error;
}
this.resources.set(data);
}
}
16 changes: 8 additions & 8 deletions libs/webcomponents/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@picsa/webcomponents",
"version": "0.0.1",
"main": "../../dist/libs/webcomponents/dist/index.cjs.js",
"module": "../../dist/libs/webcomponents/dist/index.js",
"es2015": "../../dist/libs/webcomponents/dist/esm/index.mjs",
"es2017": "../../dist/libs/webcomponents/dist/esm/index.mjs",
"types": "../../dist/libs/webcomponents/dist/types/components.d.ts",
"collection": "../../dist/libs/webcomponents/dist/collection/collection-manifest.json",
"collection:main": "../../dist/libs/webcomponents/dist/collection/index.js",
"unpkg": "../../dist/libs/webcomponents/dist/picsa-webcomponents/picsa-webcomponents.js",
"main": "./dist/index.cjs.js",
"module": "./dist/index.js",
"es2015": "./dist/esm/index.mjs",
"es2017": "./dist/esm/index.mjs",
"types": "./dist/types/components.d.ts",
"collection": "./dist/collection/collection-manifest.json",
"collection:main": "./dist/collection/index.js",
"unpkg": "./dist/picsa-webcomponents/picsa-webcomponents.js",
"files": [
"dist/",
"loader/"
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16456,7 +16456,7 @@ __metadata:
"leaflet-draw@github:enketo/Leaflet.draw#ff730785db7fcccbf2485ffcf4dffe1238a7c617":
version: 1.0.4
resolution: "leaflet-draw@https://github.com/enketo/Leaflet.draw.git#commit=ff730785db7fcccbf2485ffcf4dffe1238a7c617"
checksum: b08b88994769667f11f2b6a8937656c89cea34dafd4661abab0b48b4b97f3bddbdce7b23ddfdb8d7c6335e065530e32a70e281314afa34afa134bf68597945fc
checksum: 253998170af27f886d05b245c85429767e272647221daaf8d94ff5b86f75b8cbb96cc76a8a88492243166a214bc3b66b3ae704a81f74c862f09ac6c9495f731e
languageName: node
linkType: hard

Expand Down

0 comments on commit e02dc68

Please sign in to comment.