diff --git a/CHANGES.md b/CHANGES.md index b084a54..f2393e2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,11 @@ # Changes +## Version 0.6.1 (2022-10-04) + +- Add support to customize data cube name of IDT/Temporal Composed [`#119`](https://github.com/brazil-data-cube/dc-manager/issues/119) + + ## Version 0.6.0 (2022-09-26) - Change LICENSE to GPLv3 diff --git a/data-cube-manager/package-lock.json b/data-cube-manager/package-lock.json index fe5dfaf..0fd4b71 100644 --- a/data-cube-manager/package-lock.json +++ b/data-cube-manager/package-lock.json @@ -1,6 +1,6 @@ { "name": "data-cube-manager", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/data-cube-manager/package.json b/data-cube-manager/package.json index 00f69e8..f1bfcc3 100644 --- a/data-cube-manager/package.json +++ b/data-cube-manager/package.json @@ -1,6 +1,6 @@ { "name": "data-cube-manager", - "version": "0.6.0", + "version": "0.6.1", "license": "GPLv3", "scripts": { "ng": "ng", diff --git a/data-cube-manager/src/app/admin/admin-guard.service.ts b/data-cube-manager/src/app/admin/admin-guard.service.ts index 53a6fd3..aa84a56 100644 --- a/data-cube-manager/src/app/admin/admin-guard.service.ts +++ b/data-cube-manager/src/app/admin/admin-guard.service.ts @@ -11,6 +11,6 @@ export class AdminGuardService implements CanActivateChild { route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { const token = localStorage.getItem('DC_MANAGER_api_token') - return token ? true : false; + return !!token || token === ""; } } \ No newline at end of file diff --git a/data-cube-manager/src/app/admin/admin.reducer.ts b/data-cube-manager/src/app/admin/admin.reducer.ts index cc5d064..16a27d1 100644 --- a/data-cube-manager/src/app/admin/admin.reducer.ts +++ b/data-cube-manager/src/app/admin/admin.reducer.ts @@ -16,6 +16,7 @@ const initialState: AdminState = { definitionInfos: { bucket: '', name: '', + identity: '', version: null, public: true, resolution: null, diff --git a/data-cube-manager/src/app/admin/admin.state.ts b/data-cube-manager/src/app/admin/admin.state.ts index 80dc0b7..c4346ba 100644 --- a/data-cube-manager/src/app/admin/admin.state.ts +++ b/data-cube-manager/src/app/admin/admin.state.ts @@ -35,6 +35,7 @@ export interface IBand { export interface DefinitionCube { bucket: string; name: string; + identity: string; version: number; public: boolean; resolution: number; diff --git a/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts b/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts index 1dd718e..aaae0f5 100644 --- a/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts +++ b/data-cube-manager/src/app/admin/pages/check-cube/check-cube.component.ts @@ -12,6 +12,7 @@ import { SceneDetailsComponent } from './scene-details/scene-details.component'; import * as moment from 'moment'; import { ReprocessDialogComponent } from 'app/admin/components/reprocess-dialog/reprocess-dialog.component'; import { DomSanitizer } from '@angular/platform-browser'; +import { isIdentity } from 'app/shared/helpers/cube'; @Component({ @@ -325,7 +326,7 @@ export class CheckCubeComponent implements OnInit { } isIdentity() { - return this.cube && this.cube.name.split('_').length === 2; + return isIdentity(this.cube); } } diff --git a/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.html b/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.html index 3bd3a29..4efc8ec 100644 --- a/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.html +++ b/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.html @@ -25,22 +25,17 @@

-
+
Cube Name - - Full Name: - {{ getCubeFullName() }}_FUNC -
-
+
Version @@ -50,7 +45,7 @@

-
+
Resolution @@ -60,6 +55,16 @@

+
+ + Identity Cube Name + + + + + +
+
Temporal Composition diff --git a/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.ts b/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.ts index 2cf5465..1e534ea 100644 --- a/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.ts +++ b/data-cube-manager/src/app/admin/pages/create-cube/steps/definition/definition.component.ts @@ -13,6 +13,7 @@ import { FormGroup, FormBuilder, Validators } from '@angular/forms' import { setDefinition } from 'app/admin/admin.action' import { BucketsModal } from './buckets/buckets.component' import { CustomBandDialogComponent } from './custom-band-dialog/custom-band-dialog.component' +import { getCubeBuilderVersion } from 'app/shared/helpers/cube' @Component({ selector: 'app-create-cube-definition', @@ -49,7 +50,11 @@ export class CreateCubeDefinitionComponent implements OnInit { public dialog: MatDialog) { this.formCreateCube = this.fb.group({ bucket: ['', this.environmentVersion === 'cloud' ? [Validators.required] : []], - name: ['', [Validators.required, Validators.pattern('^[a-zA-Z0-9-]*$')]], + name: ['', [Validators.required, Validators.pattern('^[a-zA-Z0-9-_]*$')]], + identity: ['', this.supportsIdentityField() ? + [Validators.required, Validators.pattern('^[a-zA-Z0-9-_]*$')] : + [] + ], version: ['', [Validators.required]], resolution: ['', [Validators.required]], temporalComposite: [{value: '', disabled: true}, [Validators.required]], @@ -235,8 +240,7 @@ export class CreateCubeDefinitionComponent implements OnInit { indexes.push(bandIndex); } } - - this.store.dispatch(setDefinition({ + const data = { definition: { bucket: this.formCreateCube.get('bucket').value, name: this.formCreateCube.get('name').value, @@ -252,25 +256,26 @@ export class CreateCubeDefinitionComponent implements OnInit { qualityNodata: this.formCreateCube.get('qualityNodata').value, public: this.formCreateCube.get('public').value } - })) + } + if (this.supportsIdentityField()) { + data.definition['identity'] = this.formCreateCube.get('identity').value; + } + + this.store.dispatch(setDefinition(data)) this.definitonCompleted = true } } getCubeFullName() { const name = this.formCreateCube.get('name').value - const resolution = this.formCreateCube.get('resolution').value if (this.formCreateCube.get('temporalComposite').value.length) { const temporalComposite = JSON.parse(this.formCreateCube.get('temporalComposite').value) const unit = temporalComposite['unit'].replace('day', 'D').replace('month', 'M').replace('year', 'Y') - if (unit === 'null') { - return `${name}_${resolution}` - } else { - return `${name}_${resolution}_${temporalComposite['step']}${unit}` + if (unit !== 'null') { + return `${name}-${temporalComposite['step']}${unit}` } - } else { - return `${name}_${resolution}` } + return name; } getSelectedIndexes() { @@ -373,4 +378,16 @@ export class CreateCubeDefinitionComponent implements OnInit { } } } + + supportsIdentityField(): boolean { + const builderVersion = getCubeBuilderVersion(); + if (!builderVersion || this.environmentVersion === 'cloud') + return false; + + let [major, minor, patch] = builderVersion.split(".").map(value => Number.parseInt(value)); + + // Supported only >= 0.8.3 + return (major == 0 && minor >= 8 && patch >= 3) || + (major >= 1 && minor >= 0 && patch >= 0); + } } diff --git a/data-cube-manager/src/app/admin/pages/create-cube/steps/preview/preview.component.ts b/data-cube-manager/src/app/admin/pages/create-cube/steps/preview/preview.component.ts index dfb5bd0..932289d 100644 --- a/data-cube-manager/src/app/admin/pages/create-cube/steps/preview/preview.component.ts +++ b/data-cube-manager/src/app/admin/pages/create-cube/steps/preview/preview.component.ts @@ -124,18 +124,7 @@ export class CreateCubePreviewComponent implements OnInit { } getCubeName(func) { - let cubeName = this.definition.name - let complement = ''; - - if (func !== 'IDT') { - complement = `_${this.getComplementCubeName(this.definition.temporal)}`; - - if (this.environmentVersion === 'cloud') { - complement = `-${complement.split('_')[2]}` - } - } - - return `${cubeName}${complement}` + return this.definition.name } getComplementCubeName(temporalSchema) { @@ -199,6 +188,10 @@ export class CreateCubePreviewComponent implements OnInit { parameters: parameters } + if (this.definition.identity !== '') { + cube['datacube_identity'] = this.definition.identity + } + if (this.environmentVersion === 'cloud') cube['bucket'] = this.definition.bucket diff --git a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html index d0b8116..df1e24d 100644 --- a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html +++ b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.html @@ -39,7 +39,7 @@

{{ cube.title }}

Composite Function: - {{ cube.composite_function }} + {{ getCompositeFunction() }} Temporal Composition: @@ -75,7 +75,7 @@

{{ cube.title }}

- diff --git a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts index ffa1a34..c7ca364 100644 --- a/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts +++ b/data-cube-manager/src/app/admin/pages/details-cube/details-cube.component.ts @@ -11,6 +11,7 @@ import { ReprocessDialogComponent } from 'app/admin/components/reprocess-dialog/ import { UpdateCubeDialog } from 'app/admin/components/update-cube-dialog/update-cube-dialog.component'; import { DomSanitizer } from '@angular/platform-browser'; import { UpdateBandDialogComponent } from 'app/admin/components/update-band-dialog/update-band-dialog.component'; +import { getCompositeFunction } from 'app/shared/helpers/cube'; @Component({ selector: 'app-details-cube', @@ -248,6 +249,10 @@ export class DetailsCubeComponent implements OnInit { (this.cubeStatus.not_done > 0 || this.cubeStatus.done > 0 || this.cubeStatus.error > 0); } + public getCompositeFunction() { + return getCompositeFunction(this.cube); + } + /** * event used when change Map */ diff --git a/data-cube-manager/src/app/app.component.ts b/data-cube-manager/src/app/app.component.ts index 859de26..93d016b 100644 --- a/data-cube-manager/src/app/app.component.ts +++ b/data-cube-manager/src/app/app.component.ts @@ -28,18 +28,22 @@ export class AppComponent implements OnInit { this.spinner.hide() } - if (res.token) { + if (this.validToken(res.token)) { this.token = res.token } }); } ngOnInit() { - if (!this.token) { + if (!this.validToken(this.token)) { this.openTokenModal() } } + private validToken(token) { + return token || token === ""; + } + openTokenModal() { const dialogRef = this.dialog.open(TokenModal, { width: '450px', diff --git a/data-cube-manager/src/app/shared/helpers/cube.ts b/data-cube-manager/src/app/shared/helpers/cube.ts new file mode 100644 index 0000000..29e1371 --- /dev/null +++ b/data-cube-manager/src/app/shared/helpers/cube.ts @@ -0,0 +1,36 @@ +/** + * Helper to check if the given value is a string. + */ +export function isString(value: any): boolean { + return typeof value === 'string' || value instanceof String; +} + + +export function isIdentity(cube: any): boolean { + if (!cube) { + return false; + } + return getCompositeFunction(cube) === 'IDT'; +} + + +export function getCompositeFunction(cube: any): string { + if (!cube) { + return ; + } + // For compatibility + let alias = cube.composite_function; + if (!isString(cube.composite_function)) { + alias = cube.composite_function.alias + } + return alias; +} + + +export function getCubeBuilderVersion(): string { + return localStorage.getItem("DC_MANAGER_BUILDER_VERSION"); +} + +export function setCubeBuilderVersion(version: string) { + localStorage.setItem("DC_MANAGER_BUILDER_VERSION", version); +} diff --git a/data-cube-manager/src/app/shared/token/token.component.ts b/data-cube-manager/src/app/shared/token/token.component.ts index c3d7391..2a8949c 100644 --- a/data-cube-manager/src/app/shared/token/token.component.ts +++ b/data-cube-manager/src/app/shared/token/token.component.ts @@ -4,6 +4,7 @@ import { CubeBuilderService } from "app/services/cube-builder"; import { Store } from "@ngrx/store"; import { token, showLoading, closeLoading, setURLCubeBuilder } from "app/app.action"; import { MatSnackBar } from "@angular/material/snack-bar"; +import { setCubeBuilderVersion } from "../helpers/cube"; @Component({ selector: 'token-modal', @@ -24,9 +25,11 @@ export class TokenModal { async verify() { try { this.store.dispatch(showLoading()) - const _ = await this.cbs.verifyToken(this.urlService, this.token) + const resp = await this.cbs.verifyToken(this.urlService, this.token) this.store.dispatch(token({ token: this.token })) this.store.dispatch(setURLCubeBuilder({ url: this.urlService })) + + setCubeBuilderVersion(resp.version); window.location.reload(); this.dialogRef.close() @@ -36,7 +39,7 @@ export class TokenModal { verticalPosition: 'top', panelClass: 'app_snack-bar-error' }); - + } finally { this.store.dispatch(closeLoading()) }