Skip to content

Commit

Permalink
Merge pull request #47 from garrylachman/2.3.0-dev
Browse files Browse the repository at this point in the history
2.3.0 dev
  • Loading branch information
garrylachman authored Jul 25, 2019
2 parents d8c31a1 + 7e0729c commit 8b8be6d
Show file tree
Hide file tree
Showing 15 changed files with 370 additions and 23 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ After a failed search for a basic admin panel that not involves writing code or
The ElectroCRUD v1 was born in 2016, An Electron application that made it possible to create a friendly dashboard with data tables, search, widgets, filter & relations with few clicks without any experience in programming.

### ElectroCRUD v2
After a few years that the project was inactive, I decided to bring it an alive again. The codebase was build from scratch using Electron+Angular8. Many of the original functionality is still missing, but I'm working to cover backward compatibility.
After a few years that the project was inactive, I decided to bring it an alive again. The codebase was build from scratch using Electron+Angular8. The new version contains most of the features of the first version, and new features added on a weekly basis.

[![forthebadge](https://forthebadge.com/images/badges/approved-by-george-costanza.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/as-seen-on-tv.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/built-with-love.svg)](https://forthebadge.com)

Expand All @@ -25,7 +25,7 @@ After a few years that the project was inactive, I decided to bring it an alive
- [x] Add / Edit
- [x] Test connection (ssh, db)
- [ ] Export / Import
- [x] Views (represent a table)
- [x] Views (represent a table)
- [x] Add new view & Edit view configurations
- [x] Data table with pagination
- [x] Search
Expand All @@ -34,10 +34,12 @@ After a few years that the project was inactive, I decided to bring it an alive
- [x] Selection of columns to display or search by
- [x] Add new record / Edit record
- [x] Edit record
- [x] Connect existing view as sub views
- [ ] Export data in various formats like: csv, dump
- [x] Subviews (represent a sub table)
- [ ] Views relations
- [ ] One to one, One to many
- [ ] Drill from view to view
- [x] Drill from view to view (subview)
- [ ] FOREIGN KEY interactive UI
- [x] View widgets (display aggragated data in the view)
- [x] Add / Edit / Remove widgets
- [x] Aggregation functions (AVG, SUM, MIN, MAX, COUNT)
Expand All @@ -58,9 +60,9 @@ After a few years that the project was inactive, I decided to bring it an alive
## Download Binaries ![GitHub release](https://img.shields.io/github/release/garrylachman/ElectroCRUD.svg?style=for-the-badge)
We are in early beta !!!

* [Mac OSX (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.2.1-beta/ElectroCRUD-2.2.1-beta.dmg)
* [Linux (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.2.1-beta/ElectroCRUD.2.2.1-beta.AppImage)
* [Windows (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.2.1-beta/ElectroCRUD.2.2.1-beta.exe)
* [Mac OSX (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.3.0-beta/ElectroCRUD-2.3.0-beta.dmg)
* [Linux (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.3.0-beta/ElectroCRUD.2.3.0-beta.AppImage)
* [Windows (Release beta)](https://github.com/garrylachman/ElectroCRUD/releases/download/2.3.0-beta/ElectroCRUD.2.3.0-beta.exe)

## Download Sources
[ElectroCRUD on GitHub](https://github.com/garrylachman/ElectroCRUD)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ElectroCRUD",
"version": "2.2.1-beta",
"version": "2.3.0-beta",
"description": "No coding is required; Create basic CRUD (Create, Read, Update, Delete) for your Database Database in minutes",
"homepage": "https://github.com/garrylachman/ElectroCRUD",
"author": {
Expand Down
53 changes: 49 additions & 4 deletions src/app/views/configure/configure.component.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<nb-layout>

<nb-layout-column class="colored-column-primary padding-0" start>
<nb-card>
<nb-card-header><h1 class="page-header h4">{{title}}</h1></nb-card-header>
</nb-card>

<nb-layout class="inner_scroll" [withScroll]="false" [windowMode]="false">

<nb-layout-column class="colored-column-primary" start>

<nb-card [nbSpinner]="isLoading" nbSpinnerSize="giant" nbSpinnerStatus="primary">
<nb-card-header>
<div [formGroup]="viewHeaderForm">
Expand Down Expand Up @@ -45,7 +46,7 @@
</nb-card-body>
</nb-card>

<div class="row">
<div class="row" *ngIf="view?.table">
<div class="col-md-4">
<nb-card>
<nb-card-header>Terminology</nb-card-header>
Expand Down Expand Up @@ -88,6 +89,50 @@
</div>
</div>

<div class="row" *ngIf="view?.table">
<div class="col-md-6">
<nb-card>
<nb-card-header>Sub View</nb-card-header>
<nb-card-body>
<div [formGroup]="subviewForm">
<p>Connect an existing view as a subview to display child table rows.</p>
<div class="form-group">
<nb-checkbox formControlName="subviewEnabledCtrl">Enabled</nb-checkbox>
</div>

<div class="form-group margin-bottom-0_5rem">
<label class="label" >Select a view to using as a subview</label>
<nb-select formControlName="subviewViewIdCtrl" fullWidth placeholder="Select View" [disabled]="!view.subview?.enabled">
<nb-option *ngFor="let view of allViews" value="{{view.id}}">{{view.name}}</nb-option>
</nb-select>
</div>

<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="label">Select local column to match</label>
<nb-select formControlName="subviewSourceColumnCtrl" fullWidth placeholder="Local Column" [disabled]="!view.subview?.enabled && !view.subview?.view_id">
<nb-option *ngFor="let col of view?.columns" value="{{col.name}}">{{col.name}}</nb-option>
</nb-select>
</div>
</div>

<div class="col-md-6">
<div class="form-group">
<label class="label" >to match in `{{subviewTargetView?.name}}`</label>
<nb-select formControlName="subviewTargetColumnCtrl" fullWidth placeholder="Target Column" [disabled]="!view.subview?.enabled && !view.subview?.view_id">
<nb-option *ngFor="let col of subviewTargetView?.columns" value="{{col.name}}">{{col.name}}</nb-option>
</nb-select>
</div>
</div>
</div>
</div>
</nb-card-body>
</nb-card>
</div>

</div>

<nb-card>
<nb-card-header id="footer">
<button nbButton hero status="success" size="medium" (click)="save()" [disabled]="!isSaveEnabled">
Expand Down
11 changes: 11 additions & 0 deletions src/app/views/configure/configure.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ nb-select[formcontrolname="viewtTableCtrl"] {
#footer {
display: flex;
flex-direction: row-reverse;
}
::ng-deep
.inner_scroll .scrollable-container {
height: auto !important;
overflow: unset !important;
}

nb-layout-column {
padding-left: 0px !important;
padding-right: 0px !important;
padding-top: 0px !important;
}
69 changes: 66 additions & 3 deletions src/app/views/configure/configure.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ export class ConfigureComponent implements OnInit {

viewHeaderForm: FormGroup;
termForm: FormGroup;
subviewForm: FormGroup;

isSaveEnabled:boolean = false;
isHavePrimaryKey: boolean = false;
allViews: IView[] = [];
subviewTargetView: IView;

constructor(
private route: ActivatedRoute,
Expand Down Expand Up @@ -71,10 +74,26 @@ export class ConfigureComponent implements OnInit {
update: true,
delete: true
},
columns: []
columns: [],
};
}

// load all view to display in subviews form
this.allViews = this.viewsService.all(this.sessionsService.activeAccount);

// init empty subview if no value
if (!this.view.subview) {
this.view.subview = {
enabled: false,
}
} else {
// init subviewTargetView if we have already subview (edit mode)
if (this.view.subview.view_id) {
// load the target view to subviewTargetView
this.subviewTargetView = this.viewsService.get(this.view.subview.view_id);
}
}

this.viewHeaderForm = this.fb.group({
viewtNameCtrl: [this.view.name, Validators.compose([Validators.required, Validators.minLength(2)])],
viewtTableCtrl: [this.view.table || null, Validators.required]
Expand All @@ -85,8 +104,43 @@ export class ConfigureComponent implements OnInit {
termManyCtrl: [this.view.terms.many, Validators.compose([Validators.required, Validators.minLength(1)])],
});

this.subviewForm = this.fb.group({
subviewEnabledCtrl: [this.view.subview.enabled, Validators.nullValidator],
subviewViewIdCtrl: [this.view.subview.view_id || null, Validators.nullValidator],
subviewSourceColumnCtrl: [this.view.subview.ref ? this.view.subview.ref.source_column : null, Validators.nullValidator],
subviewTargetColumnCtrl: [this.view.subview.ref ? this.view.subview.ref.target_column : null, Validators.nullValidator],
});

this.subviewForm.controls['subviewEnabledCtrl'].valueChanges.subscribe(value => {
// Enable/Disable subview form
this.view.subview.enabled = value;

// Change validators on subview enable/disable change
const newValidator = value ? Validators.required : Validators.nullValidator;
this.subviewForm.controls['subviewViewIdCtrl'].setValidators([newValidator]);
this.subviewForm.controls['subviewSourceColumnCtrl'].setValidators([newValidator]);
this.subviewForm.controls['subviewTargetColumnCtrl'].setValidators([newValidator]);

this.subviewForm.controls['subviewViewIdCtrl'].updateValueAndValidity();
this.subviewForm.controls['subviewSourceColumnCtrl'].updateValueAndValidity();
this.subviewForm.controls['subviewTargetColumnCtrl'].updateValueAndValidity();

this.checkForm()
});

this.subviewForm.controls['subviewViewIdCtrl'].valueChanges.subscribe(value => {
// set target view id in subview.view_id
this.view.subview.view_id = value;

if (this.view.subview.view_id) {
// load the target view to subviewTargetView
this.subviewTargetView = this.viewsService.get(value);
}
});

this.viewHeaderForm.controls['viewtTableCtrl'].valueChanges.subscribe(value => this.selectedChange(value));
this.viewHeaderForm.valueChanges.subscribe((v) => this.checkForm());
this.subviewForm.valueChanges.subscribe((v) => this.checkForm());

await this.loadTablesList();
}
Expand Down Expand Up @@ -149,16 +203,25 @@ export class ConfigureComponent implements OnInit {
}

checkForm() {
this.isSaveEnabled = this.viewHeaderForm.valid && this.termForm.valid;
this.isSaveEnabled = this.viewHeaderForm.valid && this.termForm.valid && this.subviewForm.valid
}

save() {
if (this.viewHeaderForm.valid && this.termForm.valid) {
if (this.viewHeaderForm.valid && this.termForm.valid && this.subviewForm.valid) {
this.view.name = this.viewHeaderForm.value.viewtNameCtrl;
this.view.terms.one = this.termForm.value.termOneCtrl;
this.view.terms.many = this.termForm.value.termManyCtrl;
this.view.columns = [...this.rows] as IViewColumn[];

if (this.subviewForm.value.subviewEnabledCtrl) {
this.view.subview.enabled = this.subviewForm.value.subviewEnabledCtrl;
this.view.subview.view_id = this.subviewForm.value.subviewViewIdCtrl;
this.view.subview.ref = {
source_column: this.subviewForm.value.subviewSourceColumnCtrl,
target_column: this.subviewForm.value.subviewTargetColumnCtrl
};
}

let insertedId:number;

if (this.view.id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<ngx-datatable #subTable
class="bootstrap"
[rows]="rows"
[columns]="columns"
[loadingIndicator]="true"
[columnMode]="'force'"
[headerHeight]="30"
[footerHeight]="30"
[rowHeight]="'auto'"
[reorderable]="true"
[externalPaging]="true"
[count]="totalElements"
[offset]="offset"
[limit]="limit"
(page)='setPage($event)'
></ngx-datatable>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SubViewComponent } from './sub-view.component';

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

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SubViewComponent ]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(SubViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading

0 comments on commit 8b8be6d

Please sign in to comment.