Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Add note vcs item #81

Merged
merged 6 commits into from
Nov 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/browser/app/app-configs.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { Provider } from '@angular/core';
import { NoteCollectionActionTypes } from '../note/note-collection';
import { NoteEditorActionTypes } from '../note/note-editor';
import { NoteVcsItemFactory } from '../note/note-shared';
import { VCS_DETECT_CHANGES_EFFECT_ACTIONS } from '../vcs';
import { BaseVcsItemFactory, VCS_ITEM_MAKING_FACTORIES, VcsItemFactory } from '../vcs/vcs-view';


export const AppVcsItemFactoriesProvider: Provider = {
provide: VCS_ITEM_MAKING_FACTORIES,
useFactory(baseVcsItemFactory: BaseVcsItemFactory): VcsItemFactory<any>[] {
return [baseVcsItemFactory];
useFactory(
noteVcsItemFactory: NoteVcsItemFactory,
baseVcsItemFactory: BaseVcsItemFactory,
): VcsItemFactory<any>[] {
// 1. Note related files
// 2. Others... (asset etc.)
return [noteVcsItemFactory, baseVcsItemFactory];
},
deps: [BaseVcsItemFactory],
deps: [NoteVcsItemFactory, BaseVcsItemFactory],
};


export const AppVcsDetectChangesEffectActionsProvider: Provider = {
provide: VCS_DETECT_CHANGES_EFFECT_ACTIONS,
useValue: [
NoteCollectionActionTypes.LOAD_COLLECTION,
NoteCollectionActionTypes.LOAD_COLLECTION_COMPLETE,
NoteCollectionActionTypes.ADD_NOTE,
NoteEditorActionTypes.SAVE_NOTE_CONTENT_COMPLETE,
],
Expand Down
2 changes: 2 additions & 0 deletions src/browser/note/_all-theme.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
@import "./note-collection/all-theme";
@import "./note-editor/all-theme";
@import "./note-preview/all-theme";
@import "./note-shared/all-theme";

@mixin gd-note-all-theme($theme) {
@include gd-note-collection-all-theme($theme);
@include gd-note-editor-all-theme($theme);
@include gd-note-preview-theme($theme);
@include gd-note-shared-all-theme($theme);
}
5 changes: 5 additions & 0 deletions src/browser/note/note-shared/_all-theme.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import "./note-vcs-item/note-vcs-item-theme";

@mixin gd-note-shared-all-theme($theme) {
@include gd-note-vcs-item-theme($theme);
}
2 changes: 2 additions & 0 deletions src/browser/note/note-shared/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './note-shared.module';
export * from './note-parser';
export * from './note-parsing.model';
export * from './note-vcs-item/note-vcs-item.component';
export * from './note-vcs-item/note-vcs-item-factory';
12 changes: 10 additions & 2 deletions src/browser/note/note-shared/note-shared.module.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { UiModule } from '../../ui/ui.module';
import { NoteParser } from './note-parser';
import { NoteSnippetContentToHtmlPipe } from './note-snippet-content-to-html.pipe';
import { NoteVcsItemFactory } from './note-vcs-item/note-vcs-item-factory';
import { NoteVcsItemComponent } from './note-vcs-item/note-vcs-item.component';


@NgModule({
imports: [
CommonModule,
UiModule,
],
providers: [
NoteParser,
NoteVcsItemFactory,
],
declarations: [
NoteSnippetContentToHtmlPipe,
NoteVcsItemComponent,
],
entryComponents: [
NoteVcsItemComponent,
],
exports: [
NoteSnippetContentToHtmlPipe,
NoteVcsItemComponent,
],
})
export class NoteSharedModule {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$note-vcs-item-size: 28px;
$note-vcs-item-file-size: 20px;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@import "../../../ui/style/spacing";
@import "../../../ui/style/theming";
@import "./note-vcs-item-sizes";

@mixin gd-note-vcs-item-theme($theme) {
$foreground: map-get($theme, foreground);

.NoteVcsItem {
&__panel {
// border-top: 1px solid gd-color($foreground, divider);
}

&__fileChange {
position: relative;

&:not(:last-child):after {
position: absolute;
display: block;
width: $note-vcs-item-file-size / 2;
height: $note-vcs-item-file-size / 2;
border-left: 1px solid gd-color($foreground, secondary-text);
top: ($note-vcs-item-file-size / 2);
left: ($note-vcs-item-file-size / 2);
content: " ";
}

&:before {
position: absolute;
display: block;
width: $note-vcs-item-file-size / 2;
height: $note-vcs-item-file-size / 2;
border-left: 1px solid gd-color($foreground, secondary-text);
border-bottom: 1px solid gd-color($foreground, secondary-text);
top: 0;
left: ($note-vcs-item-file-size / 2);
content: " ";
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { TestBed } from '@angular/core/testing';
import { combineReducers, Store, StoreModule } from '@ngrx/store';
import * as path from 'path';
import { createDummies, fastTestSetup } from '../../../../../test/helpers';
import { VcsFileChange, VcsFileChangeStatusTypes } from '../../../../core/vcs';
import { LoadNoteCollectionCompleteAction } from '../../note-collection';
import { NoteItemDummy } from '../../note-collection/dummies';
import { noteReducerMap } from '../../note.reducer';
import { NoteStateWithRoot } from '../../note.state';
import { NoteVcsItemFactory } from './note-vcs-item-factory';
import { NoteVcsItemComponent } from './note-vcs-item.component';


describe('browser.note.noteShared.NoteVcsItemFactory', () => {
let factory: NoteVcsItemFactory;

let store: Store<NoteStateWithRoot>;

const noteItemDummy = new NoteItemDummy('/foo/bar', '/foo/bar/.geeks-diary/notes');

fastTestSetup();

beforeAll(() => {
TestBed.configureTestingModule({
imports: [
StoreModule.forRoot({
note: combineReducers(noteReducerMap),
}),
],
providers: [
NoteVcsItemFactory,
],
});
});

beforeEach(() => {
factory = TestBed.get(NoteVcsItemFactory);
store = TestBed.get(Store);
});

it('should output result correctly.', async () => {
const notes = createDummies(noteItemDummy, 5);
const fileChanges: VcsFileChange[] = notes.reduce((changes, note) => {
const noteFileChange: VcsFileChange = {
filePath: path.relative('/foo/bar', note.filePath),
absoluteFilePath: note.filePath,
workingDirectoryPath: '/foo/bar',
status: VcsFileChangeStatusTypes.MODIFIED,
};

const noteContentFileChange: VcsFileChange = {
filePath: path.relative('/foo/bar', note.contentFilePath),
absoluteFilePath: note.contentFilePath,
workingDirectoryPath: '/foo/bar',
status: VcsFileChangeStatusTypes.MODIFIED,
};

return changes.concat([noteFileChange, noteContentFileChange]);
}, []);

store.dispatch(new LoadNoteCollectionCompleteAction({ notes }));

const result = await factory.create(fileChanges);

expect(result.refs.length).toEqual(5);
result.refs.forEach((ref, index) => {
expect(ref._config.title).toEqual(notes[index].title);
expect(ref._config.fileChanges).toEqual([fileChanges[index * 2], fileChanges[index * 2 + 1]]);
expect(ref.component).toEqual(NoteVcsItemComponent);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Injectable } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { pipe } from 'rxjs';
import { take } from 'rxjs/operators';
import { VcsFileChange } from '../../../../core/vcs';
import { toPromise } from '../../../../libs/rx';
import { VcsItemConfig, VcsItemCreateResult, VcsItemFactory, VcsItemRef } from '../../../vcs/vcs-view';
import { NoteStateWithRoot } from '../../note.state';
import { NoteVcsItemComponent } from './note-vcs-item.component';


@Injectable()
export class NoteVcsItemFactory extends VcsItemFactory<NoteVcsItemComponent> {
constructor(
private store: Store<NoteStateWithRoot>,
) {
super();
}

async create(fileChanges: VcsFileChange[]): Promise<VcsItemCreateResult<NoteVcsItemComponent>> {
const usedFileChanges: VcsFileChange[] = [];
const refs: VcsItemRef<NoteVcsItemComponent>[] = [];

// Get notes first.
const notes = await toPromise(this.store.pipe(
select(state => state.note.collection.notes),
pipe(take(1)),
));

for (const note of notes) {
let index: number;
const willUseFileChanges: VcsFileChange[] = [];

// Note file
index = fileChanges.findIndex(change => change.absoluteFilePath === note.filePath);
if (index !== -1) {
willUseFileChanges.push(fileChanges[index]);
}

// Note content file
index = fileChanges.findIndex(change => change.absoluteFilePath === note.contentFilePath);
if (index !== -1) {
willUseFileChanges.push(fileChanges[index]);
}

if (willUseFileChanges.length > 0) {
const config: VcsItemConfig = {
title: note.title,
fileChanges: willUseFileChanges,
};

const ref = new VcsItemRef<NoteVcsItemComponent>(config);
ref.component = NoteVcsItemComponent;

usedFileChanges.push(...willUseFileChanges);
refs.push(ref);
}
}

return { refs, usedFileChanges };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div fxLayout fxLayoutAlign="start center" class="NoteVcsItem__head">
<gd-checkbox fxFlex="1 1 auto" [formControl]="checkFormControl" [fixedWidth]="true">
{{ _config.title }}
</gd-checkbox>
<button fxFlex="none" gd-icon-button aria-label="" [gdExpansionTrigger]="panel">
<gd-icon [name]="panel.expanded ? 'angle-up' : 'angle-down'"></gd-icon>
</button>
</div>

<div gdExpansionPanel #panel="gdExpansionPanel" [expanded]="false" class="NoteVcsItem__panel">
<div *ngFor="let change of _config.fileChanges" fxLayout fxLayoutAlign="start center"
class="NoteVcsItem__fileChange">
<span fxFlex="1 1 auto" class="NoteVcsItem__fileName">{{ change.filePath }}</span>
<span fxFlex="none" class="NoteVcsItem__statusIcon" [innerHTML]="getStatusIconForFileChange(change)"></span>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@import "../../../ui/style/spacing";
@import "../../../ui/button/button-sizes";
@import "./note-vcs-item-sizes";

.NoteVcsItem {
&__head {
padding: 0 $spacing-half;
width: 100%;
height: $note-vcs-item-size;
cursor: default;

gd-checkbox {
max-width: calc(100% - #{$button-size});
}
}

&__panel {
padding: $spacing-third 0;
}

&__fileChange {
$padding-left: $note-vcs-item-file-size + $spacing-half;

padding: 0 $spacing-half 0 $padding-left;
height: $note-vcs-item-file-size;
}

&__fileName {
min-width: 1px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

&__statusIcon {
display: inline-block;

> svg {
display: block;
width: 16px;
height: 16px;
}
}
}