From cd99fbf77a7dd15849dfa4a7d9ea466a59be2fe1 Mon Sep 17 00:00:00 2001 From: mustafahlvc Date: Wed, 30 Aug 2017 06:54:11 +0300 Subject: [PATCH 1/8] (Scrumboard App) added + md2 added for date-time picker, + toggleInArray func added to FuseUtils --- package-lock.json | 5 + package.json | 1 + src/app/app.module.ts | 6 +- src/app/core/fuseUtils.ts | 12 + src/app/core/modules/shared.module.ts | 7 +- src/app/core/pipes/getById.pipe.ts | 5 +- src/app/core/scss/partials/_colors.scss | 6 +- src/app/fuse-fake-db/fuse-fake-db.service.ts | 4 +- src/app/fuse-fake-db/scrumboard.ts | 787 ++++++++++++++++++ .../board/add-list/add-list.component.html | 23 + .../board/add-list/add-list.component.scss | 32 + .../board/add-list/add-list.component.ts | 57 ++ .../scrumboard/board/board.component.html | 76 ++ .../scrumboard/board/board.component.scss | 151 ++++ .../apps/scrumboard/board/board.component.ts | 60 ++ .../board/dialogs/card/card.component.html | 448 ++++++++++ .../board/dialogs/card/card.component.scss | 437 ++++++++++ .../board/dialogs/card/card.component.ts | 262 ++++++ .../label-selector.component.html | 71 ++ .../label-selector.component.scss | 37 + .../label-selector.component.ts | 70 ++ .../edit-board-name.component.html | 21 + .../edit-board-name.component.scss | 8 + .../edit-board-name.component.ts | 61 ++ .../list/add-card/add-card.component.html | 30 + .../list/add-card/add-card.component.scss | 39 + .../board/list/add-card/add-card.component.ts | 57 ++ .../board/list/card/card.component.html | 124 +++ .../board/list/card/card.component.scss | 114 +++ .../board/list/card/card.component.ts | 43 + .../edit-list-name.component.html | 17 + .../edit-list-name.component.scss | 9 + .../edit-list-name.component.ts | 59 ++ .../scrumboard/board/list/list.component.html | 47 ++ .../scrumboard/board/list/list.component.scss | 57 ++ .../scrumboard/board/list/list.component.ts | 104 +++ .../sidenavs/settings/settings.component.html | 52 ++ .../sidenavs/settings/settings.component.scss | 11 + .../sidenavs/settings/settings.component.ts | 49 ++ .../apps/scrumboard/scrumboard.component.html | 36 + .../apps/scrumboard/scrumboard.component.scss | 187 +++++ .../apps/scrumboard/scrumboard.component.ts | 103 +++ .../apps/scrumboard/scrumboard.module.ts | 64 ++ .../apps/scrumboard/scrumboard.service.ts | 174 ++++ src/app/navigation.model.ts | 6 + 45 files changed, 4022 insertions(+), 7 deletions(-) create mode 100644 src/app/fuse-fake-db/scrumboard.ts create mode 100644 src/app/main/content/apps/scrumboard/board/add-list/add-list.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/add-list/add-list.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/board.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/board.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/board.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/list/card/card.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/list/card/card.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/list/card/card.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/list/list.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/list/list.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/list/list.component.ts create mode 100644 src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html create mode 100644 src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.scss create mode 100644 src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.ts create mode 100644 src/app/main/content/apps/scrumboard/scrumboard.component.html create mode 100644 src/app/main/content/apps/scrumboard/scrumboard.component.scss create mode 100644 src/app/main/content/apps/scrumboard/scrumboard.component.ts create mode 100644 src/app/main/content/apps/scrumboard/scrumboard.module.ts create mode 100644 src/app/main/content/apps/scrumboard/scrumboard.service.ts diff --git a/package-lock.json b/package-lock.json index a4ba78d7..9cbe3f59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5941,6 +5941,11 @@ "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", "dev": true }, + "md2": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/md2/-/md2-0.0.28.tgz", + "integrity": "sha512-XQ71eTVKG3oRsGBj3lMLqL8p2inueqDXn++a2EntzWkUPlBZXPCPtlpfI9ER/LAlBKwJZQSqTzFItw7q9+vgvw==" + }, "md5.js": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", diff --git a/package.json b/package.json index 5a93b00e..acf4eda4 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "hammerjs": "^2.0.8", "highlight.js": "^9.12.0", "intl": "^1.2.5", + "md2": "0.0.28", "moment": "^2.18.1", "ngx-color-picker": "^4.3.1", "ngx-perfect-scrollbar": "^4.5.6", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a7621b15..e95f851b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -43,6 +43,10 @@ const appRoutes: Routes = [ path : 'apps/contacts', loadChildren: './main/content/apps/contacts/contacts.module#FuseContactsModule' }, + { + path : 'apps/scrumboard', + loadChildren: './main/content/apps/scrumboard/scrumboard.module#FuseScrumboardModule' + }, { path : '**', redirectTo: 'apps/dashboards/project' @@ -73,7 +77,7 @@ const appRoutes: Routes = [ UIModule, ComponentsModule ], - providers: [ + providers : [ FuseSplashScreenService, FuseConfigService ], diff --git a/src/app/core/fuseUtils.ts b/src/app/core/fuseUtils.ts index 228d0353..3278c1a6 100644 --- a/src/app/core/fuseUtils.ts +++ b/src/app/core/fuseUtils.ts @@ -90,4 +90,16 @@ export class FuseUtils return (S4() + S4()); } + + public static toggleInArray(item, array) + { + if ( array.indexOf(item) === -1 ) + { + array.push(item); + } + else + { + array.splice(array.indexOf(item), 1); + } + } } diff --git a/src/app/core/modules/shared.module.ts b/src/app/core/modules/shared.module.ts index f9c6acea..60b1d106 100644 --- a/src/app/core/modules/shared.module.ts +++ b/src/app/core/modules/shared.module.ts @@ -20,6 +20,7 @@ import { FuseMdSidenavHelperService } from '../directives/md-sidenav-helper/md-s import { FuseHljsComponent } from '../components/hljs/hljs.component'; import { FuseIfOnDomDirective } from '../directives/fuse-if-on-dom/fuse-if-on-dom.directive'; import { FuseMaterialColorPickerComponent } from '../components/material-color-picker/material-color-picker.component'; +import { Md2Module } from 'md2'; @NgModule({ declarations : [ @@ -41,7 +42,8 @@ import { FuseMaterialColorPickerComponent } from '../components/material-color-p ReactiveFormsModule, ColorPickerModule, NgxDnDModule, - NgxDatatableModule + NgxDatatableModule, + Md2Module ], exports : [ FlexLayoutModule, @@ -59,7 +61,8 @@ import { FuseMaterialColorPickerComponent } from '../components/material-color-p NgxDnDModule, NgxDatatableModule, FuseIfOnDomDirective, - FuseMaterialColorPickerComponent + FuseMaterialColorPickerComponent, + Md2Module ], entryComponents: [ FuseConfirmDialogComponent diff --git a/src/app/core/pipes/getById.pipe.ts b/src/app/core/pipes/getById.pipe.ts index e2797aad..5993697f 100644 --- a/src/app/core/pipes/getById.pipe.ts +++ b/src/app/core/pipes/getById.pipe.ts @@ -1,6 +1,9 @@ import { Pipe, PipeTransform } from '@angular/core'; -@Pipe({name: 'getById'}) +@Pipe({ + name: 'getById', + pure: false +}) export class GetByIdPipe implements PipeTransform { transform(value: any[], id: number, property: string): any diff --git a/src/app/core/scss/partials/_colors.scss b/src/app/core/scss/partials/_colors.scss index 6a92fe6d..7d61345f 100644 --- a/src/app/core/scss/partials/_colors.scss +++ b/src/app/core/scss/partials/_colors.scss @@ -54,7 +54,8 @@ $matColorHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400 &.secondary-text, .secondary-text, .mat-icon, - .icon { + .icon, + .md2-datepicker-button { color: rgba(0, 0, 0, 0.54); } @@ -79,7 +80,8 @@ $matColorHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400 @else { .mat-icon, - .icon { + .icon, + .md2-datepicker-button { color: rgba(255, 255, 255, 1); } diff --git a/src/app/fuse-fake-db/fuse-fake-db.service.ts b/src/app/fuse-fake-db/fuse-fake-db.service.ts index 736b6ef6..4f9bbec1 100644 --- a/src/app/fuse-fake-db/fuse-fake-db.service.ts +++ b/src/app/fuse-fake-db/fuse-fake-db.service.ts @@ -12,6 +12,7 @@ import { SearchFakeDb } from './search'; import { QuickPanelFakeDb } from './quick-panel'; import { IconsFakeDb } from './icons'; import { ProjectsDashboardDb } from './projects-dashboard'; +import { ScrumboardFakeDb } from './scrumboard'; export class FuseFakeDbService implements InMemoryDbService { @@ -42,7 +43,8 @@ export class FuseFakeDbService implements InMemoryDbService 'quick-panel-events' : QuickPanelFakeDb.events, 'icons' : IconsFakeDb.icons, 'projects-dashboard-projects': ProjectsDashboardDb.projects, - 'projects-dashboard-widgets' : ProjectsDashboardDb.widgets + 'projects-dashboard-widgets' : ProjectsDashboardDb.widgets, + 'scrumboard-boards' : ScrumboardFakeDb.boards }; } } diff --git a/src/app/fuse-fake-db/scrumboard.ts b/src/app/fuse-fake-db/scrumboard.ts new file mode 100644 index 00000000..aac7d95b --- /dev/null +++ b/src/app/fuse-fake-db/scrumboard.ts @@ -0,0 +1,787 @@ +export class ScrumboardFakeDb +{ + public static boards = [ + { + 'id' : '32gfhaf2', + 'name' : 'ACME Frontend Application', + 'uri' : 'acme-frontend-application', + 'settings': { + 'color' : 'fuse-dark', + 'subscribed' : false, + 'cardCoverImages': true + }, + 'lists' : [ + { + 'id' : '56027cf5a2ca3839a5d36103', + 'name' : 'Design', + 'idCards': [ + '5603a2a3cab0c8300f6096b3', + '44d1.2b51ea6cc2b5d.21f4a3412e857.8ffa2d8b44ad9.ac87215ed53a1.67d4921ad8f8d.9f318bcb2' + ] + }, + { + 'id' : '56127cf2a2ca3539g7d36103', + 'name' : 'Development', + 'idCards': [ + '2837273da9b93dd84243s0f9', + '5787b7e4740c57bf0dffd5b6', + '5637273da9b93bb84743a0f9', + '7987.9740ba532b0d4.f9d12243f7362.507c0738dc561.87fba0a03df6e.75e6508cacf10.7a9835b54' + ] + }, + { + 'id' : 'faf244627326f1249525763d', + 'name' : 'Upcoming Features', + 'idCards': [ + 'd9005a4b89ed2aadca48a6ad', + 'f6b9d7a9247e5d794a081927', + '80ed.24ad3b18e2668.f28fbbceeeff9.5a834620a42f1.5909be19a2bf2.6c4a54947ce2d.da356b0c1', + '0ad2.7862f947bc456.f42b446df54cb.d1dd9e93601a1.9deb1406d1404.0b3c278fc7001.733341b42', + 'bad3.51be8ad33acaf.9540ecb37f7e8.6bee596cfe7d3.44c68bee289c4.b96ed0b9f0af7.e14846035' + ] + }, + { + 'id' : 'ad7d.9fffac5dff412.c83bca6853767.8fd7549b2b1ca.ceda8a01774c4.a5cf3976e87e4.ce79eeeea', + 'name' : 'Known Bugs', + 'idCards': [ + 'acc6.9c673cd2f5e35.521e91d8d5991.4b2a95e0539d1.027930c0743c5.7ad1ea7bea476.e8fbe6347', + '3279.3d69b40cc0b75.690252b6bea08.1e1789b0b7c2e.2f264b8661ce2.84d5f56910e23.429be5e8a', + 'ba01.8e1a43f92a03a.0022bd5cbb9ba.275c64d911d8c.880e0846a3966.f75ff43e53ad.48ad612e7' + ] + } + ], + 'cards' : [ + { + 'id' : '2837273da9b93dd84243s0f9', + 'name' : 'Update generators', + 'description' : 'Current generator doesn\'t support Node.js 6 and above.', + 'idAttachmentCover': '', + 'idMembers' : [ + '26027s1930450d8bf7b10828' + ], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [ + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'AngularCLI could be a nice alternative.', + 'time' : 'now' + } + ], + 'activities' : [], + 'due' : null + }, + { + 'id' : '5603a2a3cab0c8300f6096b3', + 'name' : 'Change background colors', + 'description' : '', + 'idAttachmentCover': '67027cahbe3b52ecf2dc631c', + 'idMembers' : [ + '76027g1930450d8bf7b10958' + ], + 'idLabels' : [ + '56027e4119ad3a5dc28b36cd', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [ + { + 'id' : '67027cahbe3b52ecf2dc631c', + 'name': 'mail.jpg', + 'src' : 'assets/images/scrumboard/mail.jpg', + 'time': 'Added Nov 3 at 15:22AM', + 'type': 'image' + }, + { + 'id' : '56027cfcbe1b72ecf1fc452a', + 'name': 'calendar.jpg', + 'src' : 'assets/images/scrumboard/calendar.jpg', + 'time': 'Added Nov 1 at 12:34PM', + 'type': 'image' + } + ], + 'subscribed' : true, + 'checklists' : [ + { + 'id' : '63021cfdbe1x72wcf1fc451v', + 'name' : 'Checklist', + 'checkItemsChecked': 1, + 'checkItems' : [ + { + 'name' : 'Implement a calendar library', + 'checked': false + }, + { + 'name' : 'Replace event colors with Material Design colors', + 'checked': true + }, + { + 'name' : 'Replace icons with Material Design icons', + 'checked': false + }, + { + 'name' : 'Use moment.js', + 'checked': false + } + ] + }, + { + 'name' : 'Checklist 2', + 'id' : '74031cfdbe1x72wcz1dc166z', + 'checkItemsChecked': 1, + 'checkItems' : [ + { + 'name' : 'Replace event colors with Material Design colors', + 'checked': true + }, + { + 'name' : 'Replace icons with Material Design icons', + 'checked': false + }, + { + 'name' : 'Use moment.js', + 'checked': false + } + ] + } + ], + 'checkItems' : 7, + 'checkItemsChecked': 2, + 'comments' : [ + { + 'idMember': '56027c1930450d8bf7b10758', + 'message' : 'We should be able to add moment.js without any problems', + 'time' : '12 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'I added a link for a page that might help us deciding the colors', + 'time' : '30 mins. ago' + } + ], + 'activities' : [ + { + 'idMember': '56027c1930450d8bf7b10758', + 'message' : 'added a comment', + 'time' : '12 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'added a comment', + 'time' : '30 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'attached a link', + 'time' : '45 mins. ago' + } + ], + 'due' : 'Tue Aug 29 2017 13:16:34 GMT+0300 (Turkey Standard Time)' + }, + { + 'id' : '5637273da9b93bb84743a0f9', + 'name' : 'Fix splash screen bugs', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '56027c1930450d8bf7b10758' + ], + 'idLabels' : [ + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [], + 'subscribed' : true, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : 'd9005a4b89ed2aadca48a6ad', + 'name' : 'Add alternative authentication pages', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '36027j1930450d8bf7b10158' + ], + 'idLabels' : [ + '6540635g19ad3s5dc31412b2', + '56027e4119ad3a5dc28b36cd' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [ + { + 'id' : 'dbfb.99bd0ad37dabc.e05046f0c824d.18f26bb524c96.78bebc8488634.240c0ee6a5e45.4cb872965', + 'name' : 'Pages', + 'checkItemsChecked': 2, + 'checkItems' : [ + { + 'name' : 'Login', + 'checked': true + }, + { + 'name' : 'Register', + 'checked': true + }, + { + 'name' : 'Lost Password', + 'checked': false + }, + { + 'name' : 'Recover Password', + 'checked': false + }, + { + 'name' : 'Activate Account', + 'checked': false + } + ] + } + ], + 'checkItems' : 5, + 'checkItemsChecked': 2, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : '5787b7e4740c57bf0dffd5b6', + 'name' : 'Fix the console', + 'description' : 'We need to fix the console asap!', + 'idAttachmentCover': '', + 'idMembers' : [], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd' + ], + 'attachments' : [], + 'subscribed' : true, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [ + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'I\'m on it!', + 'time' : 'now' + } + ], + 'activities' : [], + 'due' : 'Fri Sep 07 2018 15:00:00 GMT+0300 (Turkey Standard Time)' + }, + { + 'id' : 'f6b9d7a9247e5d794a081927', + 'name' : 'New media player', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '76027g1930450d8bf7b10958', + '56027c1930450d8bf7b10758', + '26027s1930450d8bf7b10828' + ], + 'idLabels' : [ + '5640635e19ad3a5dc21416b2', + '6540635g19ad3s5dc31412b2' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : 'acc6.9c673cd2f5e35.521e91d8d5991.4b2a95e0539d1.027930c0743c5.7ad1ea7bea476.e8fbe6347', + 'name' : 'Memory Leak', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '36027j1930450d8bf7b10158' + ], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : '3279.3d69b40cc0b75.690252b6bea08.1e1789b0b7c2e.2f264b8661ce2.84d5f56910e23.429be5e8a', + 'name' : 'Broken toolbar on profile page', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '26027s1930450d8bf7b10828' + ], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [ + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'This should be a medium priority bug, shouldn\'t it?', + 'time' : 'now' + } + ], + 'activities' : [], + 'due' : null + }, + { + 'id' : 'ba01.8e1a43f92a03a.0022bd5cbb9ba.275c64d911d8c.880e0846a3966.f75ff43e53ad.48ad612e7', + 'name' : 'Button hover style', + 'description' : 'If there are 3 or more buttons in certain page, weird flashing happens when you hover over the red ones.', + 'idAttachmentCover': '', + 'idMembers' : [ + '26027s1930450d8bf7b10828' + ], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [], + 'subscribed' : true, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : 'Wed Mar 08 2017 12:00:00 GMT+0300 (Turkey Standard Time)' + }, + { + 'id' : '80ed.24ad3b18e2668.f28fbbceeeff9.5a834620a42f1.5909be19a2bf2.6c4a54947ce2d.da356b0c1', + 'name' : 'New header designs', + 'description' : '', + 'idAttachmentCover': '12027cafbe3b52ecf2ef632c', + 'idMembers' : [], + 'idLabels' : [ + '56027e4119ad3a5dc28b36cd', + '6540635g19ad3s5dc31412b2', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [ + { + 'id' : '12027cafbe3b52ecf2ef632c', + 'name': 'header-.jpg', + 'src' : 'assets/images/scrumboard/header-1.jpg', + 'time': 'Added Nov 3 at 15:22AM', + 'type': 'image' + }, + { + 'id' : '55027ced1e1a12ecf1fced2a', + 'name': 'header-2.jpg', + 'src' : 'assets/images/scrumboard/header-2.jpg', + 'time': 'Added Nov 1 at 12:34PM', + 'type': 'image' + } + ], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [ + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'Currently we have two new designs ready to ship.', + 'time' : 'now' + } + ], + 'activities' : [], + 'due' : null + }, + { + 'id' : '0ad2.7862f947bc456.f42b446df54cb.d1dd9e93601a1.9deb1406d1404.0b3c278fc7001.733341b42', + 'name' : 'Fixed footer', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [ + '26027s1930450d8bf7b10828', + '56027c1930450d8bf7b10758' + ], + 'idLabels' : [ + '6540635g19ad3s5dc31412b2' + ], + 'attachments' : [], + 'subscribed' : true, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : 'bad3.51be8ad33acaf.9540ecb37f7e8.6bee596cfe7d3.44c68bee289c4.b96ed0b9f0af7.e14846035', + 'name' : 'Collapsable navigation', + 'description' : '', + 'idAttachmentCover': '', + 'idMembers' : [], + 'idLabels' : [ + '6540635g19ad3s5dc31412b2' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [ + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'I\'m not sure why we re-doing the navigation. The current collapsable navigation works flawlessly.', + 'time' : 'now' + } + ], + 'activities' : [], + 'due' : null + }, + { + 'id' : '44d1.2b51ea6cc2b5d.21f4a3412e857.8ffa2d8b44ad9.ac87215ed53a1.67d4921ad8f8d.9f318bcb2', + 'name' : 'Mail app new layout', + 'description' : 'Current layout has lots of flaws in mobile. Outlook view should help with that.', + 'idAttachmentCover': '', + 'idMembers' : [ + '56027c1930450d8bf7b10758', + '26027s1930450d8bf7b10828', + '76027g1930450d8bf7b10958', + '36027j1930450d8bf7b10158' + ], + 'idLabels' : [ + '56027e4119ad3a5dc28b36cd', + '26022e4129ad3a5sc28b36cd' + ], + 'attachments' : [], + 'subscribed' : false, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + }, + { + 'id' : '7987.9740ba532b0d4.f9d12243f7362.507c0738dc561.87fba0a03df6e.75e6508cacf10.7a9835b54', + 'name' : 'API recover and monitoring', + 'description' : 'We need a service to monitor and recover failed APIs.', + 'idAttachmentCover': '', + 'idMembers' : [ + '36027j1930450d8bf7b10158', + '76027g1930450d8bf7b10958' + ], + 'idLabels' : [ + '26022e4129ad3a5sc28b36cd', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [], + 'subscribed' : true, + 'checklists' : [ + { + 'id' : '6926.2b31d119e4a.889401e0ca7a0.13ad8ce2e569d.976e54e8b5d87.456afccd7e820.d6c77106a', + 'name' : 'API Monitoring', + 'checkItemsChecked': 2, + 'checkItems' : [ + { + 'name' : 'Simple dashboard design', + 'checked': false + }, + { + 'name' : 'Should be able to see different time periods on the same dashboard', + 'checked': true + }, + { + 'name' : 'Different colors for different clusters', + 'checked': true + } + ] + }, + { + 'id' : '7c22.5261c7924387f.248e8b1d32205.003f7a9f501d1.1d48dcdbe8b23.8099dcc5f75a7.29a966196', + 'name' : 'API Recovery', + 'checkItemsChecked': 1, + 'checkItems' : [ + { + 'name' : 'Warning notifications to all developers', + 'checked': false + }, + { + 'name' : 'Immediate recovery options attached to the notifications', + 'checked': true + }, + { + 'name' : 'Backups every 6hours', + 'checked': false + } + ] + } + ], + 'checkItems' : 6, + 'checkItemsChecked': 3, + 'comments' : [], + 'activities' : [], + 'due' : 'Fri Feb 02 2017 14:20:34 GMT+0300 (Turkey Standard Time)' + } + ], + 'members' : [ + { + 'id' : '56027c1930450d8bf7b10758', + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + { + 'id' : '26027s1930450d8bf7b10828', + 'name' : 'Danielle Obrien', + 'avatar': 'assets/images/avatars/danielle.jpg' + }, + { + 'id' : '76027g1930450d8bf7b10958', + 'name' : 'James Lewis', + 'avatar': 'assets/images/avatars/james.jpg' + }, + { + 'id' : '36027j1930450d8bf7b10158', + 'name' : 'Vincent Munoz', + 'avatar': 'assets/images/avatars/vincent.jpg' + } + ], + 'labels' : [ + { + 'id' : '26022e4129ad3a5sc28b36cd', + 'name' : 'High Priority', + 'color': 'md-red-500-bg' + }, + { + 'id' : '56027e4119ad3a5dc28b36cd', + 'name' : 'Design', + 'color': 'md-orange-400-bg' + }, + { + 'id' : '5640635e19ad3a5dc21416b2', + 'name' : 'App', + 'color': 'md-blue-600-bg' + }, + { + 'id' : '6540635g19ad3s5dc31412b2', + 'name' : 'Feature', + 'color': 'md-green-400-bg' + } + ] + }, + { + 'id' : '27cfcbe1', + 'name' : 'ACME Backend Application', + 'uri' : 'acme-backend-application', + 'settings': { + 'color' : 'blue-grey', + 'subscribed' : false, + 'cardCoverImages': true + }, + 'lists' : [ + { + 'id' : '56027cf5a2ca3839a5d36103', + 'name' : 'Designs', + 'idCards': [ + '5603a2a3cab0c8300f6096b3' + ] + }, + { + 'id' : '56127cf2a2ca3539g7d36103', + 'name' : 'Development', + 'idCards': [ + '5637273da9b93bb84743a0f9' + ] + } + ], + 'cards' : [ + { + 'id' : '5603a2a3cab0c8300f6096b3', + 'name' : 'Calendar App Design', + 'description' : '', + 'idAttachmentCover': '56027cfcbe1b72ecf1fc452a', + 'idMembers' : [ + '56027c1930450d8bf7b10758', + '36027j1930450d8bf7b10158' + ], + 'idLabels' : [ + '56027e4119ad3a5dc28b36cd', + '5640635e19ad3a5dc21416b2' + ], + 'attachments' : [ + { + 'id' : '56027cfcbe1b72ecf1fc452a', + 'name': 'calendar-app-design.jpg', + 'src' : 'assets/images/scrumboard/calendar.jpg', + 'time': 'Added Nov 1 at 12:34PM', + 'type': 'image' + }, + { + 'id' : '67027cahbe3b52ecf2dc631c', + 'url' : 'assets/images/scrumboard/calendar.jpg', + 'time': 'Added Nov 3 at 15:22AM', + 'type': 'link' + } + ], + 'subscribed' : true, + 'checklists' : [ + { + 'id' : '63021cfdbe1x72wcf1fc451v', + 'name' : 'Checklist', + 'checkItemsChecked': 1, + 'checkItems' : [ + { + 'name' : 'Implement a calendar library', + 'checked': false + }, + { + 'name' : 'Replace event colors with Material Design colors', + 'checked': true + }, + { + 'name' : 'Replace icons with Material Design icons', + 'checked': false + }, + { + 'name' : 'Use moment.js', + 'checked': false + } + ] + }, + { + 'name' : 'Checklist 2', + 'id' : '74031cfdbe1x72wcz1dc166z', + 'checkItemsChecked': 1, + 'checkItems' : [ + { + 'name' : 'Replace event colors with Material Design colors', + 'checked': true + }, + { + 'name' : 'Replace icons with Material Design icons', + 'checked': false + }, + { + 'name' : 'Use moment.js', + 'checked': false + } + ] + } + ], + 'checkItems' : 7, + 'checkItemsChecked': 2, + 'comments' : [ + { + 'idMember': '56027c1930450d8bf7b10758', + 'message' : 'We should be able to add moment.js without any problems', + 'time' : '12 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'I added a link for a page that might help us deciding the colors', + 'time' : '30 mins. ago' + } + ], + 'activities' : [ + { + 'idMember': '56027c1930450d8bf7b10758', + 'message' : 'added a comment', + 'time' : '12 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'added a comment', + 'time' : '30 mins. ago' + }, + { + 'idMember': '36027j1930450d8bf7b10158', + 'message' : 'attached a link', + 'time' : '45 mins. ago' + } + ], + 'due' : null + }, + { + 'id' : '5637273da9b93bb84743a0f9', + 'name' : 'Fix Splash Screen bugs', + 'description' : '', + 'idAttachmentCover': '5603a2ae2bbd55bb2db57478', + 'idMembers' : [ + '56027c1930450d8bf7b10758' + ], + 'idLabels' : [], + 'attachments' : [ + { + 'id' : '5603a2ae2bbd55bb2db57478', + 'name': 'mail-app-design.jpg', + 'src' : 'assets/images/scrumboard/mail.jpg', + 'time': 'Added Nov 1 at 12:34PM', + 'type': 'image' + } + ], + 'subscribed' : true, + 'checklists' : [], + 'checkItems' : 0, + 'checkItemsChecked': 0, + 'comments' : [], + 'activities' : [], + 'due' : null + } + ], + 'members' : [ + { + 'id' : '56027c1930450d8bf7b10758', + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + { + 'id' : '26027s1930450d8bf7b10828', + 'name' : 'Danielle Obrien', + 'avatar': 'assets/images/avatars/danielle.jpg' + }, + { + 'id' : '76027g1930450d8bf7b10958', + 'name' : 'James Lewis', + 'avatar': 'assets/images/avatars/james.jpg' + }, + { + 'id' : '36027j1930450d8bf7b10158', + 'name' : 'Vincent Munoz', + 'avatar': 'assets/images/avatars/vincent.jpg' + } + ], + 'labels' : [ + { + 'id' : '56027e4119ad3a5dc28b36cd', + 'name' : 'Design', + 'color': 'md-red-500-bg' + }, + { + 'id' : '5640635e19ad3a5dc21416b2', + 'name' : 'App', + 'color': 'md-blue-500-bg' + }, + { + 'id' : '6540635g19ad3s5dc31412b2', + 'name' : 'Feature', + 'color': 'md-green-400-bg' + } + ] + } + ]; +} diff --git a/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.html b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.html new file mode 100644 index 00000000..5103cd74 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.html @@ -0,0 +1,23 @@ +
+ + + +
+ + + + + +
+
+ diff --git a/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.scss b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.scss new file mode 100644 index 00000000..9f53dafc --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.scss @@ -0,0 +1,32 @@ +:host { + .new-list { + border-radius: 2px; + background-color: #EEF0F2; + + .new-list-form-button { + text-transform: none; + font-size: 15px; + padding: 0 16px; + height: 64px; + margin: 0; + width: 100%; + + md-icon { + border-radius: 50%; + height: 40px; + width: 40px; + line-height: 40px; + margin-right: 16px; + } + } + + .new-list-form { + padding: 16px; + height: 64px; + + > input { + height: 100%; + } + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts new file mode 100644 index 00000000..f0265579 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts @@ -0,0 +1,57 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'fuse-scrumboard-board-add-list', + templateUrl: './add-list.component.html', + styleUrls : ['./add-list.component.scss'] +}) +export class FuseScrumboardBoardAddListComponent implements OnInit +{ + formActive = false; + form: FormGroup; + @Output() onlistAdd = new EventEmitter(); + @ViewChildren('nameInput') nameInputField; + + constructor( + private formBuilder: FormBuilder + ) + { + } + + ngOnInit() + { + + } + + openForm() + { + this.form = this.formBuilder.group({ + name: [''] + }); + this.formActive = true; + this.focusNameField(); + } + + closeForm() + { + this.formActive = false; + } + + focusNameField() + { + setTimeout(() => { + this.nameInputField.first.nativeElement.focus(); + }); + } + + onFormSubmit() + { + if ( this.form.valid ) + { + this.onlistAdd.next(this.form.getRawValue().name); + this.formActive = false; + } + } + +} diff --git a/src/app/main/content/apps/scrumboard/board/board.component.html b/src/app/main/content/apps/scrumboard/board/board.component.html new file mode 100644 index 00000000..255efcf1 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/board.component.html @@ -0,0 +1,76 @@ + + +
+ +
+ +
+ + +
+ +
+ + + +
+ remove_red_eye + + +
+ + + +
+ + + + +
+ + +
+ +
+ + +
+ + +
+ + + + + + + + + + +
+ +
+ +
+ + + + + +
diff --git a/src/app/main/content/apps/scrumboard/board/board.component.scss b/src/app/main/content/apps/scrumboard/board/board.component.scss new file mode 100644 index 00000000..8f805abf --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/board.component.scss @@ -0,0 +1,151 @@ +@import "src/app/core/scss/fuse"; + +:host { + + md-sidenav-container { + width: 100%; + height: 100%; + + md-sidenav { + width: 320px !important; + min-width: 320px !important; + max-width: 320px !important; + } + + #board { + flex-direction: column; + display: flex; + height: 100%; + + > .header { + position: relative; + height: 96px; + min-height: 96px; + max-height: 96px; + background-image: none; + z-index: 49; + + .header-content { + + .header-boards-button { + margin: 0; + } + + .header-board-name { + font-size: 16px; + + .board-subscribe { + margin-right: 8px; + } + + .editable-buttons { + + md-icon { + color: #FFFFFF !important; + } + } + } + + .right-side { + + > .md-button:last-child { + margin-right: 0; + } + } + + } + } + + #board-selector { + position: absolute; + top: 96px; + right: 0; + left: 0; + height: 192px; + z-index: 48; + padding: 24px; + opacity: 1; + + .board-list-item { + width: 128px; + height: 192px; + padding: 16px; + cursor: pointer; + position: relative; + + .board-name { + text-align: center; + padding: 16px 0; + } + + .selected-icon { + position: absolute; + top: 0; + left: 50%; + width: 32px; + height: 32px; + margin-left: -16px; + border-radius: 50%; + text-align: center; + color: white; + + i { + line-height: 32px !important; + } + } + + &.add-new-board { + opacity: 0.6; + } + } + } + + .board-content-wrapper { + position: relative; + + .board-content { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 100%; + background: #E5E7E8; + padding: 24px; + overflow-y: hidden; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + + .list-sortable-placeholder { + background: rgba(0, 0, 0, 0.06); + margin-right: 24px; + } + + .new-list-wrapper { + width: 344px; + min-width: 344px; + max-width: 344px; + padding-right: 24px; + } + + } + } + } + } +} + +.is-mobile { + + #board { + + .list-card { + + .list-card-sort-handle { + display: block; + } + } + } +} + +.list-card-sort-helper { +} diff --git a/src/app/main/content/apps/scrumboard/board/board.component.ts b/src/app/main/content/apps/scrumboard/board/board.component.ts new file mode 100644 index 00000000..9eecc068 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/board.component.ts @@ -0,0 +1,60 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ScrumboardService } from '../scrumboard.service'; +import { Subscription } from 'rxjs/Subscription'; +import { FuseUtils } from '../../../../../core/fuseUtils'; +import { Location } from '@angular/common'; + +@Component({ + selector : 'fuse-scrumboard-board', + templateUrl: './board.component.html', + styleUrls : ['./board.component.scss'] +}) +export class FuseScrumboardBoardComponent implements OnInit, OnDestroy +{ + board: any; + onBoardChanged: Subscription; + + constructor( + private route: ActivatedRoute, + private location: Location, + private scrumboardService: ScrumboardService + ) + { + } + + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + }); + } + + onListAdd(newListName) + { + if ( newListName === '' ) + { + return; + } + const newList = { + id : FuseUtils.generateGUID(), + name : newListName, + idCards: [] + }; + + this.scrumboardService.addList(newList); + } + + onBoardNameChanged(newName) + { + this.scrumboardService.updateBoard(); + this.location.go('/apps/scrumboard/boards/' + this.board.id + '/' + this.board.uri); + } + + ngOnDestroy() + { + this.onBoardChanged.unsubscribe(); + } +} diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html new file mode 100644 index 00000000..857cb539 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html @@ -0,0 +1,448 @@ + + +
+ +
+ + +
+ + + + + + + + +
+ + + +
+ + + + + + + + +
+ + + +
+ + + + +
+ +
+ +

{{ member.name }}

+
+
+
+
+
+ + + + + + + +
+ + + + + +
+ + + + + + +
+ +
+
+ + + + + + + +
+ + + + +
+ +
+ + + + +
+
+ +
+ +
+ + +
+ {{board.name}} + chevron_right + {{list.name}} +
+ + + +
+ + + + +
+ + +
+ + +
+ remove_red_eye +
+ + + +
+
+ + + +
+ + + +
+ + + +
+ + +
+ +
+
+ label + Labels +
+
+ + + {{board.labels|getById:labelId:'name'}} + close + + +
+
+ +
+
+ supervisor_account + Members +
+
+ + + + close + + +
+
+
+ + + +
+ +
+ +
+ attachment + Attachments +
+ +
+ +
+ +
+ +
+
+ +
+ +
+ {{item.name}} + star + +
+ + {{item.time}} + +
+ + + + + +
+ +
+
+ +
+
+ LINK +
+
+ {{item.url}} + {{item.time}} +
+
+
+ + +
+
+
+ + + +
+ +
+ +
+ + check_box + + {{checklist.name}} + + +
+ + + + +
+ +
+ +
+ +
+ + + {{checklist.checkItemsChecked}} / {{checklist.checkItems.length}} + + + + +
+ +
+ +
+ +
+ + + + + +
+ + + +
+
+ +
+ +
+ add + + + + +
+ + +
+ +
+
+
+ + + +
+ +
+ +
+ comment + Comments +
+ +
+
+ +
+ + + + +
+ +
+ +
+
+ +
+ + + +
+
+ {{board.members | getById: comment.idMember:'name'}} +
+
{{comment.message}}
+
{{comment.time}}
+
+
+
+
+
+ + + +
+ +
+ +
+ list + Activity +
+ +
+
+ +
{{board.members| getById:activity.idMember:'name'}}
+
{{activity.message}}
+
{{activity.time}}
+
+
+ +
+
+ + +
+ +
diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.scss b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.scss new file mode 100644 index 00000000..859c9927 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.scss @@ -0,0 +1,437 @@ +@import "src/app/core/scss/fuse"; + +:host { + display: flex; + flex-direction: column; +} + +.scrumboard-card-dialog { + + .mat-dialog-container { + padding: 0; + width: 720px; + + .mat-toolbar { + + .due-date { + + md2-datepicker { + min-width: initial; + + .md2-datepicker-trigger { + padding: 0; + + .md2-datepicker-button { + display: block; + position: relative; + top: 0; + left: 0; + line-height: normal; + } + + .md2-datepicker-input { + display: none; + } + } + } + } + } + + .mat-dialog-content { + position: relative; + background-color: #F5F5F5; + + .card-breadcrumb { + font-weight: 500; + font-size: 14px; + } + + .card-subscribe { + margin-right: 8px; + color: rgba(0, 0, 0, 0.6); + } + + .picker { + width: 140px; + min-width: 140px; + + } + + .card-name { + width: 100%; + font-size: 24px; + + .editable-input { + font-size: 24px; + } + } + + .due-date { + + md2-datepicker { + width: 180px; + min-width: 180px; + + .md2-datepicker-trigger { + padding-top: 5px; + padding-bottom: 5px; + + .md2-datepicker-button { + top: 0; + } + + .md2-datepicker-input { + min-width: initial; + } + } + } + + .remove-due-date { + } + } + + .description { + padding-bottom: 16px; + } + + .sections { + + .section { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + margin-bottom: 32px; + + &:last-child { + border-bottom: none; + margin-bottom: 0; + + .section-content { + padding-bottom: 0; + } + } + + .section-header { + font-size: 16px; + + md-icon { + margin-right: 8px; + color: rgba(0, 0, 0, 0.6); + } + + .section-title { + font-weight: 500; + } + } + + .section-content { + padding: 24px 0 32px 0; + } + + .labels { + + .section-content { + padding: 8px 0 32px 0; + } + + .label-chips { + + box-shadow: none; + padding: 0; + + .label-chip { + display: block; + + .chip-remove { + cursor: pointer; + } + } + } + } + + .members { + + .section-content { + padding: 8px 0 32px 0; + } + + .member-chips { + box-shadow: none; + padding: 0; + + .member-chip { + padding: 4px 12px 4px 4px; + + .member-chip-avatar { + width: 32px; + border-radius: 50%; + } + + .chip-remove { + cursor: pointer; + } + } + } + } + + .attachments { + + .attachment { + margin-bottom: 16px; + + .attachment-preview { + background-color: #EEF0F2; + width: 160px; + height: 128px; + background-size: contain; + background-position: 50% 50%; + background-repeat: no-repeat; + margin-right: 24px; + font-weight: 500; + color: rgba(0, 0, 0, 0.6); + } + + .attachment-content { + + .attachment-url, + .attachment-name { + font-weight: 500; + font-size: 16px; + } + + .attachment-is-cover { + margin-left: 6px; + } + + .attachment-time { + color: rgba(0, 0, 0, 0.6); + } + + .attachment-actions-button { + background-color: white; + text-transform: capitalize; + margin: 12px 0 0 0; + padding-left: 12px; + + md-icon { + margin-left: 8px; + color: rgba(0, 0, 0, 0.6); + } + } + } + } + + .add-attachment-button { + margin: 0; + + md-icon { + color: rgba(0, 0, 0, 0.6); + margin-right: 8px; + } + + span { + font-weight: 500; + text-transform: capitalize; + } + } + } + + .checklist { + + .checklist-progress { + margin-bottom: 16px; + + .checklist-progress-value { + margin-right: 12px; + font-weight: 500; + white-space: nowrap; + font-size: 14px; + } + + .checklist-progressbar { + } + } + + .editable-wrap { + flex: 1 + } + + .check-items { + + .check-item { + + md-checkbox { + margin-bottom: 0; + + .md-label { + font-size: 14px; + } + + &.md-checked { + + .md-label { + text-decoration: line-through; + color: rgba(0, 0, 0, 0.6); + } + } + } + } + } + + .new-check-item-form { + padding-top: 16px; + + md-input-container { + margin: 0; + } + + .md-button { + margin: 0 0 0 16px; + } + } + } + + .comments { + + .comment { + margin-bottom: 16px; + + .comment-member-avatar { + width: 32px; + height: 32px; + border-radius: 50%; + margin-right: 16px; + } + + .comment-member-name { + font-size: 14px; + font-weight: 500; + } + + .comment-time { + font-size: 12px; + } + + .comment-bubble { + position: relative; + padding: 8px; + background-color: white; + border: 1px solid rgb(220, 223, 225); + font-size: 14px; + margin: 4px 0; + + &:after, + &:before { + content: ' '; + position: absolute; + width: 0; + height: 0; + } + + &:after { + left: -7px; + right: auto; + top: 0px; + bottom: auto; + border: 11px solid; + border-color: white transparent transparent transparent; + } + + &:before { + left: -9px; + right: auto; + top: -1px; + bottom: auto; + border: 8px solid; + border-color: rgb(220, 223, 225) transparent transparent transparent; + } + } + + &.new-comment { + + md-input-container { + margin: 0; + } + } + } + } + + .activities { + + .activity { + margin-bottom: 12px; + + .activity-member-avatar { + width: 24px; + height: 24px; + border-radius: 50%; + margin-right: 16px; + } + + .activity-member-name { + font-size: 14px; + font-weight: 500; + margin-right: 8px; + } + + .activity-message { + font-size: 14px; + margin-right: 8px; + } + + .activity-time { + font-size: 12px; + } + } + } + } + } + } + + } +} + +.scrumboard-members-menu { + width: 240px; + .mat-checkbox-layout, + .mat-checkbox-label { + display: flex; + flex: 1; + } +} + +.scrumboard-labels-menu { + + .mat-menu-content { + padding-bottom: 0; + + .mat-checkbox-layout, + .mat-checkbox-label { + display: flex; + flex: 1; + } + + .views { + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + width: 240px; + min-width: 240px; + max-width: 240px; + min-height: 240px; + + .view { + position: absolute; + width: 240px; + height: 100%; + bottom: 0; + left: 0; + right: 0; + top: 0; + + > .header { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + } + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts new file mode 100644 index 00000000..73d8b3eb --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts @@ -0,0 +1,262 @@ +import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; +import { MD_DIALOG_DATA, MdDialogRef, MdMenuTrigger } from '@angular/material'; +import { Subscription } from 'rxjs/Subscription'; +import { ScrumboardService } from '../../../scrumboard.service'; +import { NgForm } from '@angular/forms/src/forms'; +import { FuseUtils } from '../../../../../../../core/fuseUtils'; + +@Component({ + selector : 'fuse-scrumboard-board-card-dialog', + templateUrl : './card.component.html', + styleUrls : ['./card.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy +{ + card: any; + board: any; + list: any; + + onBoardChanged: Subscription; + toggleInArray = FuseUtils.toggleInArray; + + @ViewChild('checklistMenuTrigger') checklistMenu: MdMenuTrigger; + @ViewChild('newCheckListTitleField') newCheckListTitleField; + + constructor( + public dialogRef: MdDialogRef, + @Inject(MD_DIALOG_DATA) private data: any, + private scrumboardService: ScrumboardService + ) + { + + } + + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + + this.card = this.board.cards.find((_card) => { + return this.data.cardId === _card.id; + }); + + this.list = this.board.lists.find((_list) => { + return this.data.listId === _list.id; + }); + }); + } + + /** + * Remove Due date + */ + removeDueDate() + { + this.card.due = ''; + this.updateCard(); + } + + /** + * Toggle Subscribe + */ + toggleSubscribe() + { + this.card.subscribed = !this.card.subscribed; + + this.updateCard(); + } + + /** + * Toggle Cover Image + * @param attachmentId + */ + toggleCoverImage(attachmentId) + { + if ( this.card.idAttachmentCover === attachmentId ) + { + this.card.idAttachmentCover = ''; + } + else + { + this.card.idAttachmentCover = attachmentId; + } + + this.updateCard(); + } + + /** + * Remove Attachment + * @param attachment + */ + removeAttachment(attachment) + { + if ( attachment.id === this.card.idAttachmentCover ) + { + this.card.idAttachmentCover = ''; + } + + this.card.attachments.splice(this.card.attachments.indexOf(attachment), 1); + + this.updateCard(); + } + + /** + * Remove Checklist + * @param checklist + */ + removeChecklist(checklist) + { + this.card.checklists.splice(this.card.checklists.indexOf(checklist), 1); + + this.updateCard(); + } + + /** + * Update Checked Count + * @param list + */ + updateCheckedCount(list) + { + const checkItems = list.checkItems; + let checkedItems = 0; + let allCheckedItems = 0; + let allCheckItems = 0; + + for ( const checkItem of checkItems ) + { + if ( checkItem.checked ) + { + checkedItems++; + } + } + + list.checkItemsChecked = checkedItems; + + for ( const item of this.card.checklists ) + { + allCheckItems += item.checkItems.length; + allCheckedItems += item.checkItemsChecked; + } + + this.card.checkItems = allCheckItems; + this.card.checkItemsChecked = allCheckedItems; + + this.updateCard(); + } + + /** + * Remove Checklist Item + * @param checkItem + * @param checklist + */ + removeChecklistItem(checkItem, checklist) + { + checklist.checkItems.splice(checklist.checkItems.indexOf(checkItem), 1); + + this.updateCheckedCount(checklist); + + this.updateCard(); + } + + /** + * Add Check Item + * @param {NgForm} form + * @param checkList + */ + addCheckItem(form: NgForm, checkList) + { + const checkItemVal = form.value.checkItem; + + if ( !checkItemVal || checkItemVal === '' ) + { + return; + } + + const newCheckItem = { + 'name' : checkItemVal, + 'checked': false + }; + + checkList.checkItems.push(newCheckItem); + + this.updateCheckedCount(checkList); + + form.setValue({checkItem: ''}); + + this.updateCard(); + } + + /** + * Add Checklist + * @param {NgForm} form + */ + addChecklist(form: NgForm) + { + this.card.checklists.push({ + id : FuseUtils.generateGUID(), + name : form.value.checklistTitle, + checkItemsChecked: 0, + checkItems : [] + }); + + form.setValue({checklistTitle: ''}); + form.resetForm(); + this.checklistMenu.closeMenu(); + this.updateCard(); + } + + /** + * On Checklist Menu Open + */ + onChecklistMenuOpen() + { + setTimeout(() => { + this.newCheckListTitleField._mdInputChild.focus(); + }); + } + + /** + * Add New Comment + * @param {NgForm} form + */ + addNewComment(form: NgForm) + { + const newCommentText = form.value.newComment; + + const newComment = { + idMember: '36027j1930450d8bf7b10158', + message : newCommentText, + time : 'now' + }; + + this.card.comments.unshift(newComment); + + form.setValue({newComment: ''}); + + this.updateCard(); + } + + /** + * Remove Card + */ + removeCard() + { + this.dialogRef.close(); + this.scrumboardService.removeCard(this.card.id, this.list.id); + } + + /** + * Update Card + */ + updateCard() + { + this.scrumboardService.updateCard(this.card); + } + + ngOnDestroy() + { + this.onBoardChanged.unsubscribe(); + } +} diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.html b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.html new file mode 100644 index 00000000..dd9cb0d3 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.html @@ -0,0 +1,71 @@ +
+ +
+ +
+
Labels
+ +
+ +
+ +
+ + + {{label.name}} + + + +
+
+
+ +
+ +
+
Edit Label
+ +
+ +
+ + + + + +
+ +
+ +
+ +
+
Add Label
+ +
+ +
+ +
+ + + + + +
+ + +
+
+
diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.scss b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.scss new file mode 100644 index 00000000..ff96a72e --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.scss @@ -0,0 +1,37 @@ +.scrumboard-labels-menu { + + .mat-menu-content { + padding-bottom: 0; + + .mat-checkbox-layout, + .mat-checkbox-label { + display: flex; + flex: 1; + } + + .views { + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + width: 240px; + min-width: 240px; + max-width: 240px; + min-height: 240px; + + .view { + position: absolute; + width: 240px; + height: 100%; + bottom: 0; + left: 0; + right: 0; + top: 0; + + > .header { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + } + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts new file mode 100644 index 00000000..9eda6022 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/label-selector/label-selector.component.ts @@ -0,0 +1,70 @@ +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { Subscription } from 'rxjs/Subscription'; +import { ScrumboardService } from '../../../../scrumboard.service'; +import { FuseUtils } from '../../../../../../../../core/fuseUtils'; +import { Animations } from '../../../../../../../../core/animations'; + +@Component({ + selector : 'fuse-scrumboard-label-selector', + templateUrl : './label-selector.component.html', + styleUrls : ['./label-selector.component.scss'], + encapsulation: ViewEncapsulation.None, + animations : [Animations.slideInLeft, Animations.slideInRight] +}) + +export class FuseScrumboardLabelSelectorComponent implements OnInit, OnDestroy +{ + board: any; + @Input('card') card: any; + @Output() onCardLabelsChange = new EventEmitter(); + + labelsMenuView = 'labels'; + selectedLabel: any; + newLabel = { + 'id' : '', + 'name' : '', + 'color': 'md-blue-400-bg' + }; + toggleInArray = FuseUtils.toggleInArray; + + onBoardChanged: Subscription; + + constructor( + private scrumboardService: ScrumboardService + ) + { + } + + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + }); + } + + cardLabelsChanged() + { + this.onCardLabelsChange.next(); + } + + onLabelChange() + { + this.scrumboardService.updateBoard(); + } + + addNewLabel() + { + this.newLabel.id = FuseUtils.generateGUID(); + this.board.labels.push(Object.assign({}, this.newLabel)); + this.newLabel.name = ''; + this.labelsMenuView = 'labels'; + } + + ngOnDestroy() + { + this.onBoardChanged.unsubscribe(); + } + +} diff --git a/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.html b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.html new file mode 100644 index 00000000..5a743fe3 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.html @@ -0,0 +1,21 @@ +
+ {{board.name}} + +
+ + +
+ + + + + +
diff --git a/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.scss b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.scss new file mode 100644 index 00000000..36f8f043 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.scss @@ -0,0 +1,8 @@ +:host { + .board-name { + text-overflow: ellipsis; + overflow: hidden; + font-size: 15px; + font-weight: 500; + } +} diff --git a/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts new file mode 100644 index 00000000..ddcbf583 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts @@ -0,0 +1,61 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'fuse-scrumboard-edit-board-name', + templateUrl: './edit-board-name.component.html', + styleUrls : ['./edit-board-name.component.scss'] +}) +export class FuseScrumboardEditBoardNameComponent implements OnInit +{ + formActive = false; + form: FormGroup; + @Input() board; + @Output() onNameChanged = new EventEmitter(); + @ViewChildren('nameInput') nameInputField; + + constructor( + private formBuilder: FormBuilder + ) + { + } + + ngOnInit() + { + + } + + openForm() + { + this.form = this.formBuilder.group({ + name: [this.board.name] + }); + this.formActive = true; + this.focusNameField(); + } + + closeForm() + { + this.formActive = false; + } + + focusNameField() + { + setTimeout(() => { + this.nameInputField.first.nativeElement.focus(); + }); + } + + onFormSubmit() + { + if ( this.form.valid ) + { + this.board.name = this.form.getRawValue().name; + this.board.uri = encodeURIComponent(this.board.name).replace(/%20/g, '-').toLowerCase(); + + this.onNameChanged.next(this.board.name); + this.formActive = false; + } + } + +} diff --git a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html new file mode 100644 index 00000000..74a65988 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html @@ -0,0 +1,30 @@ +
+
+ add +
+ Add a card +
+ +
+ +
+ + + + + +
+ + + + +
+
+
diff --git a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.scss b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.scss new file mode 100644 index 00000000..80fd08b3 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.scss @@ -0,0 +1,39 @@ +:host { + .add-card-button { + position: relative; + height: 48px; + min-height: 48px; + padding: 0 16px; + text-align: left; + text-transform: none; + font-weight: 500; + font-size: 14px; + background-color: #DCDFE2; + cursor: pointer; + border-radius: 2px; + + md-icon { + margin-right: 8px; + color: rgba(0, 0, 0, 0.6); + } + } + + .add-card-form-wrapper { + background-color: #DCDFE2; + + .add-card-form { + z-index: 999; + background: white; + display: block; + position: relative; + padding: 8px; + border-top: 1px solid rgba(0, 0, 0, 0.12); + + md-input-container { + width: 100%; + margin: 0; + padding: 12px 8px; + } + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts new file mode 100644 index 00000000..977f1fd3 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts @@ -0,0 +1,57 @@ +import { Component, ContentChildren, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'fuse-scrumboard-board-add-card', + templateUrl: './add-card.component.html', + styleUrls : ['./add-card.component.scss'] +}) +export class FuseScrumboardBoardAddCardComponent implements OnInit +{ + formActive = false; + form: FormGroup; + @Output() onCardAdd = new EventEmitter(); + @ViewChildren('nameInput') nameInputField; + + constructor( + private formBuilder: FormBuilder + ) + { + } + + ngOnInit() + { + } + + openForm() + { + this.form = this.formBuilder.group({ + name: '' + }); + this.formActive = true; + this.focusNameField(); + } + + closeForm() + { + this.formActive = false; + } + + focusNameField() + { + setTimeout(() => { + this.nameInputField.first._mdInputChild.focus(); + }); + } + + onFormSubmit() + { + if ( this.form.valid ) + { + const cardName = this.form.getRawValue().name; + this.onCardAdd.next(cardName); + this.formActive = false; + } + } +} + diff --git a/src/app/main/content/apps/scrumboard/board/list/card/card.component.html b/src/app/main/content/apps/scrumboard/board/list/card/card.component.html new file mode 100644 index 00000000..fd772ed0 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/card/card.component.html @@ -0,0 +1,124 @@ + +
+ +
+ + + +
+ + +
+ +
+ + + +
+ + + + +
+ + + +
{{card.name}}
+ + +
+ + + + access_time + {{card.due | date:'mediumDate'}} + + + + + + + check_circle + {{card.checkItemsChecked}} + / + {{card.checkItems}} + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ + + + + diff --git a/src/app/main/content/apps/scrumboard/board/list/card/card.component.scss b/src/app/main/content/apps/scrumboard/board/list/card/card.component.scss new file mode 100644 index 00000000..79d56b2e --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/card/card.component.scss @@ -0,0 +1,114 @@ +@import "src/app/core/scss/fuse"; + +:host { + position: relative; + display: block; + width: 100%; + margin: 16px 0; + background-color: white; + color: #000; + border-radius: 2px; + transition: box-shadow 150ms ease; + cursor: pointer; + + &.ui-sortable-helper { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); + } + + .list-card-sort-handle { + display: none; + position: absolute; + top: 0; + right: 0; + padding: 4px; + background: rgba(255, 255, 255, 0.8); + } + + .list-card-cover { + } + + .list-card-details { + padding: 16px 16px 0 16px; + + .list-card-labels { + margin-bottom: 6px; + + .list-card-label { + width: 32px; + height: 6px; + border-radius: 6px; + margin: 0 6px 6px 0; + } + } + + .list-card-name { + font-size: 14px; + font-weight: 500; + margin-bottom: 12px; + } + + .list-card-badges { + margin-bottom: 12px; + + .badge { + margin-right: 8px; + padding: 4px 8px; + border-radius: 2px; + background-color: rgba(0, 0, 0, 0.4); + color: #FFFFFF; + + md-icon { + margin-right: 4px; + } + + &.due-date { + background-color: mat-color(mat-palette($mat-green));; + + &.overdue { + background-color: mat-color(mat-palette($mat-red)); + } + } + + &.check-items { + + &.completed { + background-color: mat-color(mat-palette($mat-green)); + } + } + } + } + + .list-card-members { + margin-bottom: 12px; + + .list-card-member { + margin-right: 8px; + + .list-card-member-avatar { + border-radius: 50%; + width: 32px; + height: 32px; + } + } + } + } + + .list-card-footer { + border-top: 1px solid rgba(0, 0, 0, 0.12); + padding: 0 16px; + + .list-card-footer-item { + height: 48px; + margin-right: 12px; + color: rgba(0, 0, 0, 0.66); + + .value { + padding-left: 8px; + } + + &:last-of-type { + margin-right: 0; + } + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/list/card/card.component.ts b/src/app/main/content/apps/scrumboard/board/list/card/card.component.ts new file mode 100644 index 00000000..8ec3ab68 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/card/card.component.ts @@ -0,0 +1,43 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ScrumboardService } from '../../../scrumboard.service'; +import * as moment from 'moment'; + +@Component({ + selector : 'fuse-scrumboard-board-card', + templateUrl: './card.component.html', + styleUrls : ['./card.component.scss'] +}) +export class FuseScrumboardBoardCardComponent implements OnInit +{ + @Input() cardId; + card: any; + board: any; + + constructor( + private route: ActivatedRoute, + private scrumboardService: ScrumboardService + ) + { + } + + ngOnInit() + { + this.board = this.route.snapshot.data.board; + this.card = this.board.cards.filter((card) => { + return this.cardId === card.id; + })[0]; + } + + /** + * Is the card overdue? + * + * @param cardDate + * @returns {boolean} + */ + isOverdue(cardDate) + { + return moment() > moment(new Date(cardDate)); + } + +} diff --git a/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.html b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.html new file mode 100644 index 00000000..c8218cad --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.html @@ -0,0 +1,17 @@ +
+ {{list.name}} +
+ +
+ + + + + +
diff --git a/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.scss b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.scss new file mode 100644 index 00000000..aee46891 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.scss @@ -0,0 +1,9 @@ +:host { + .list-header-name { + text-overflow: ellipsis; + overflow: hidden; + font-size: 15px; + font-weight: 500; + cursor: pointer; + } +} diff --git a/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts new file mode 100644 index 00000000..bb2cc7b2 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts @@ -0,0 +1,59 @@ +import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector : 'fuse-scrumboard-board-edit-list-name', + templateUrl: './edit-list-name.component.html', + styleUrls : ['./edit-list-name.component.scss'] +}) +export class FuseScrumboardBoardEditListNameComponent implements OnInit +{ + formActive = false; + form: FormGroup; + @Input() list; + @Output() onNameChanged = new EventEmitter(); + @ViewChildren('nameInput') nameInputField; + + constructor( + private formBuilder: FormBuilder + ) + { + } + + ngOnInit() + { + + } + + openForm() + { + this.form = this.formBuilder.group({ + name: [this.list.name] + }); + this.formActive = true; + this.focusNameField(); + } + + closeForm() + { + this.formActive = false; + } + + focusNameField() + { + setTimeout(() => { + this.nameInputField.first.nativeElement.focus(); + }); + } + + onFormSubmit() + { + if ( this.form.valid ) + { + this.list.name = this.form.getRawValue().name; + this.onNameChanged.next(this.list.name); + this.formActive = false; + } + } + +} diff --git a/src/app/main/content/apps/scrumboard/board/list/list.component.html b/src/app/main/content/apps/scrumboard/board/list/list.component.html new file mode 100644 index 00000000..ae544bd8 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/list.component.html @@ -0,0 +1,47 @@ +
+ + +
+ + + + +
+ + + + +
+ +
+ + + +
+ +
+ + + +
+
+ + + + + + +
diff --git a/src/app/main/content/apps/scrumboard/board/list/list.component.scss b/src/app/main/content/apps/scrumboard/board/list/list.component.scss new file mode 100644 index 00000000..75cc7d82 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/list.component.scss @@ -0,0 +1,57 @@ +:host { + width: 344px; + min-width: 344px; + max-width: 344px; + padding-right: 24px; + height: 100%; + + &.ui-sortable-helper .list { + box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); + } + + .list { + max-height: 100%; + background-color: #EEF0F2; + color: #000; + border-radius: 2px; + transition: box-shadow 150ms ease; + + .list-header { + height: 64px; + min-height: 64px; + padding: 0 0 0 16px; + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + + + } + + .list-content { + position: relative; + overflow: hidden; + overflow-y: auto; + min-height: 0; + + .list-cards { + position: relative; + min-height: 32px; + padding: 0 16px; + + .card-sortable-placeholder { + background: rgba(0, 0, 0, 0.06); + } + + > div { + transition: none !important; + } + } + } + + .list-footer { + display: flex; + flex-direction: column; + flex: 1 0 auto; + min-height: 48px; + } + + } +} diff --git a/src/app/main/content/apps/scrumboard/board/list/list.component.ts b/src/app/main/content/apps/scrumboard/board/list/list.component.ts new file mode 100644 index 00000000..e471340a --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/list/list.component.ts @@ -0,0 +1,104 @@ +import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { FuseUtils } from '../../../../../../core/fuseUtils'; +import { ScrumboardService } from 'app/main/content/apps/scrumboard/scrumboard.service'; +import { ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; +import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar'; +import { MdDialog } from '@angular/material'; +import { FuseScrumboardCardDialogComponent } from '../dialogs/card/card.component'; + +@Component({ + selector : 'fuse-scrumboard-board-list', + templateUrl: './list.component.html', + styleUrls : ['./list.component.scss'] +}) +export class FuseScrumboardBoardListComponent implements OnInit, OnDestroy +{ + board: any; + dialogRef: any; + + @Input() list; + @ViewChild(PerfectScrollbarDirective) listScroll: PerfectScrollbarDirective; + + onBoardChanged: Subscription; + + constructor( + private route: ActivatedRoute, + private scrumboardService: ScrumboardService, + public dialog: MdDialog + ) + { + } + + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + }); + + } + + onListNameChanged(newListName) + { + this.list.name = newListName; + } + + onCardAdd(newCardName) + { + if ( newCardName === '' ) + { + return; + } + + const newCard = { + id : FuseUtils.generateGUID(), + name : newCardName, + description : '', + idAttachmentCover: '', + idMembers : [], + idLabels : [], + attachments : [], + subscribed : false, + checklists : [], + checkItems : 0, + checkItemsChecked: 0, + comments : [], + activities : [], + due : null + }; + + this.scrumboardService.addCard(this.list.id, newCard); + + setTimeout(() => { + this.listScroll.scrollToBottom(0, 400); + }); + + } + + removeList(listId) + { + this.scrumboardService.removeList(listId); + } + + openCardDialog(cardId) + { + this.dialogRef = this.dialog.open(FuseScrumboardCardDialogComponent, { + panelClass: 'scrumboard-card-dialog', + data : { + cardId: cardId, + listId: this.list.id + } + }); + this.dialogRef.afterClosed() + .subscribe(response => { + + }); + } + + ngOnDestroy() + { + this.onBoardChanged.unsubscribe(); + } +} diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html new file mode 100644 index 00000000..47485e4b --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html @@ -0,0 +1,52 @@ + +
+
Settings
+
+ + + +
+ + +
+ diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.scss b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.scss new file mode 100644 index 00000000..678b3c81 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.scss @@ -0,0 +1,11 @@ +:host { + display: flex; + flex-direction: column; + flex: 1 0 auto; + height: 100%; + + > .header { + flex: 0 1 auto; + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + } +} diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.ts b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.ts new file mode 100644 index 00000000..0e539149 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs/Subscription'; +import { ScrumboardService } from '../../../scrumboard.service'; + +@Component({ + selector : 'fuse-scrumboard-board-settings', + templateUrl: './settings.component.html', + styleUrls : ['./settings.component.scss'] +}) +export class FuseScrumboardBoardSettingsSidenavComponent implements OnInit +{ + board: any; + onBoardChanged: Subscription; + + constructor( + private scrumboardService: ScrumboardService + ) + { + + } + + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + }); + } + + toggleCardCover() + { + this.board.settings.cardCoverImages = !this.board.settings.cardCoverImages; + this.updateBoard(); + } + + toggleSubcription() + { + this.board.settings.subscribed = !this.board.settings.subscribed; + this.updateBoard(); + } + + updateBoard() + { + this.scrumboardService.onBoardChanged.next(this.board); + this.scrumboardService.updateBoard(); + } + +} diff --git a/src/app/main/content/apps/scrumboard/scrumboard.component.html b/src/app/main/content/apps/scrumboard/scrumboard.component.html new file mode 100644 index 00000000..f617a2d9 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/scrumboard.component.html @@ -0,0 +1,36 @@ + +
+ + +
+ +

Scrumboard App

+ + +
+ + +
+ assessment +
{{board.name}}
+
+ + + +
+ add_circle +
Add new board
+
+ + +
+ + +
+ + +
+ diff --git a/src/app/main/content/apps/scrumboard/scrumboard.component.scss b/src/app/main/content/apps/scrumboard/scrumboard.component.scss new file mode 100644 index 00000000..13eb32d4 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/scrumboard.component.scss @@ -0,0 +1,187 @@ +@import "src/app/core/scss/fuse"; + +:host { + min-height: 100%; + + #board-selector { + margin-top: 88px; + + .board-list { + padding: 32px 0; + + .board-list-item { + min-width: 210px; + width: 210px; + padding: 24px 0; + margin: 16px; + border-radius: 2px; + background: rgba(0, 0, 0, 0.12); + cursor: pointer; + + &:hover { + @include mat-elevation(4); + } + + .board-name { + padding-top: 16px; + font-weight: 500; + } + } + } + } +} + +#scrumboard { + height: 100%; + + > .header { + position: relative; + height: 96px; + min-height: 96px; + max-height: 96px; + background-image: none; + z-index: 49; + + .header-content { + + .header-boards-button { + margin: 0; + } + + .header-board-name { + font-size: 16px; + + .board-subscribe { + margin-right: 8px; + } + + .editable-buttons { + + md-icon { + color: #FFFFFF !important; + } + } + } + + .right-side { + + > .md-button:last-child { + margin-right: 0; + } + } + + } + } + + #board-selector { + position: absolute; + top: 96px; + right: 0; + left: 0; + height: 192px; + z-index: 48; + padding: 24px; + opacity: 1; + + .board-list-item { + width: 128px; + height: 192px; + padding: 16px; + cursor: pointer; + position: relative; + + .board-name { + text-align: center; + padding: 16px 0; + } + + .selected-icon { + position: absolute; + top: 0; + left: 50%; + width: 32px; + height: 32px; + margin-left: -16px; + border-radius: 50%; + text-align: center; + color: white; + + i { + line-height: 32px !important; + } + } + + &.add-new-board { + opacity: 0.6; + } + } + } + + .content { + padding: 0; + background: transparent; + } + + .editable-click { + cursor: pointer; + text-decoration: none; + color: inherit; + border-bottom: none; + } + + .editable-wrap { + display: block; + position: relative; + + .editable-controls { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + + .editable-input { + width: inherit; + background-color: white; + padding: 8px; + border: 1px solid rgba(0, 0, 0, 0.12); + } + + .editable-buttons { + display: inherit; + + .md-button { + margin: 0; + + &:first-of-type { + padding-right: 0; + } + + .icon-cancel { + color: rgba(0, 0, 0, 0.32); + } + } + } + } + } + + .board-selector-backdrop { + z-index: 47; + } +} + +// RESPONSIVE +@include media-breakpoint(xs) { + #scrumboard { + + .header { + height: 120px; + max-height: 120px; + min-height: 120px; + + } + + #board-selector { + top: 120px; + } + } +} diff --git a/src/app/main/content/apps/scrumboard/scrumboard.component.ts b/src/app/main/content/apps/scrumboard/scrumboard.component.ts new file mode 100644 index 00000000..c3c51247 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/scrumboard.component.ts @@ -0,0 +1,103 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { ScrumboardService } from './scrumboard.service'; +import { Subscription } from 'rxjs/Subscription'; +import { FuseUtils } from '../../../../core/fuseUtils'; +import { Router } from '@angular/router'; + +@Component({ + selector : 'fuse-scrumboard', + templateUrl: './scrumboard.component.html', + styleUrls : ['./scrumboard.component.scss'] +}) +export class FuseScrumboardComponent implements OnInit, OnDestroy +{ + boards: any[]; + onBoardsChanged: Subscription; + + constructor( + private router: Router, + private scrumboardService: ScrumboardService + ) + { + + } + + ngOnInit() + { + this.onBoardsChanged = + this.scrumboardService.onBoardsChanged + .subscribe(boards => { + this.boards = boards; + }); + + } + + newBoard() + { + const newBoard = { + name : 'Untitled Board', + uri : 'untitled-board', + id : FuseUtils.generateGUID(), + settings: { + color : '', + subscribed : true, + cardCoverImages: true + }, + lists : [], + cards : [], + members : [ + { + id : '56027c1930450d8bf7b10758', + name : 'Alice Freeman', + avatar: 'assets/images/avatars/alice.jpg' + }, + { + id : '26027s1930450d8bf7b10828', + name : 'Danielle Obrien', + avatar: 'assets/images/avatars/danielle.jpg' + }, + { + id : '76027g1930450d8bf7b10958', + name : 'James Lewis', + avatar: 'assets/images/avatars/james.jpg' + }, + { + id : '36027j1930450d8bf7b10158', + name : 'Vincent Munoz', + avatar: 'assets/images/avatars/vincent.jpg' + } + ], + labels : [ + { + id : '26022e4129ad3a5sc28b36cd', + name : 'High Priority', + color: 'red' + }, + { + id : '56027e4119ad3a5dc28b36cd', + name : 'Design', + color: 'orange' + }, + { + id : '5640635e19ad3a5dc21416b2', + name : 'App', + color: 'blue' + }, + { + id : '6540635g19ad3s5dc31412b2', + name : 'Feature', + color: 'green' + } + ] + }; + + this.scrumboardService.createNewBoard(newBoard).then(() => { + this.router.navigate(['/apps/scrumboard/boards/' + newBoard.id + '/' + newBoard.uri]); + }); + } + + ngOnDestroy() + { + this.onBoardsChanged.unsubscribe(); + } +} diff --git a/src/app/main/content/apps/scrumboard/scrumboard.module.ts b/src/app/main/content/apps/scrumboard/scrumboard.module.ts new file mode 100644 index 00000000..1ea08217 --- /dev/null +++ b/src/app/main/content/apps/scrumboard/scrumboard.module.ts @@ -0,0 +1,64 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../../../core/modules/shared.module'; +import { RouterModule, Routes } from '@angular/router'; +import { FuseScrumboardComponent } from './scrumboard.component'; +import { BoardResolve, ScrumboardService } from './scrumboard.service'; +import { FuseScrumboardBoardComponent } from './board/board.component'; +import { FuseScrumboardBoardListComponent } from './board/list/list.component'; +import { FuseScrumboardBoardCardComponent } from './board/list/card/card.component'; +import { FuseScrumboardBoardEditListNameComponent } from './board/list/edit-list-name/edit-list-name.component'; +import { FuseScrumboardBoardAddCardComponent } from './board/list/add-card/add-card.component'; +import { FuseScrumboardBoardAddListComponent } from './board/add-list/add-list.component'; +import { FuseScrumboardCardDialogComponent } from './board/dialogs/card/card.component'; +import { FuseScrumboardLabelSelectorComponent } from './board/dialogs/card/label-selector/label-selector.component'; +import { FuseScrumboardEditBoardNameComponent } from './board/edit-board-name/edit-board-name.component'; +import { FuseScrumboardBoardSettingsSidenavComponent } from './board/sidenavs/settings/settings.component'; + +const routes: Routes = [ + { + path : 'boards', + component: FuseScrumboardComponent, + resolve : { + scrumboard: ScrumboardService + } + }, + { + path : 'boards/:boardId/:boardUri', + component: FuseScrumboardBoardComponent, + resolve : { + board: BoardResolve + } + }, + { + path : '**', + redirectTo: 'boards' + } +]; + +@NgModule({ + declarations : [ + FuseScrumboardComponent, + FuseScrumboardBoardComponent, + FuseScrumboardBoardListComponent, + FuseScrumboardBoardCardComponent, + FuseScrumboardBoardEditListNameComponent, + FuseScrumboardBoardAddCardComponent, + FuseScrumboardBoardAddListComponent, + FuseScrumboardCardDialogComponent, + FuseScrumboardLabelSelectorComponent, + FuseScrumboardEditBoardNameComponent, + FuseScrumboardBoardSettingsSidenavComponent + ], + imports : [ + SharedModule, + RouterModule.forChild(routes) + ], + providers : [ + ScrumboardService, + BoardResolve + ], + entryComponents: [FuseScrumboardCardDialogComponent] +}) +export class FuseScrumboardModule +{ +} diff --git a/src/app/main/content/apps/scrumboard/scrumboard.service.ts b/src/app/main/content/apps/scrumboard/scrumboard.service.ts new file mode 100644 index 00000000..f26c3e9e --- /dev/null +++ b/src/app/main/content/apps/scrumboard/scrumboard.service.ts @@ -0,0 +1,174 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { Http } from '@angular/http'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +@Injectable() +export class ScrumboardService implements Resolve +{ + boards: any[]; + routeParams: any; + board: any; + + onBoardsChanged: BehaviorSubject = new BehaviorSubject([]); + onBoardChanged: BehaviorSubject = new BehaviorSubject([]); + + constructor(private http: Http) + { + } + + /** + * Resolve + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable | Promise | any} + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any + { + this.routeParams = route.params; + + return new Promise((resolve, reject) => { + Promise.all([ + this.getBoards() + ]).then( + () => { + resolve(); + }, + reject + ); + }); + } + + getBoards(): Promise + { + return new Promise((resolve, reject) => { + this.http.get('api/scrumboard-boards') + .subscribe(response => { + this.boards = response.json().data; + this.onBoardsChanged.next(this.boards); + resolve(this.boards); + }, reject); + }); + } + + getBoard(boardId): Promise + { + return new Promise((resolve, reject) => { + this.http.get('api/scrumboard-boards/' + boardId) + .subscribe(response => { + this.board = response.json().data; + this.onBoardChanged.next(this.board); + resolve(this.board); + }, reject); + }); + } + + addCard(listId, newCard) + { + this.board.lists.map((list) => { + if ( list.id === listId ) + { + return list.idCards.push(newCard.id); + } + }); + + this.board.cards.push(newCard); + + return this.updateBoard(); + } + + addList(newList) + { + + this.board.lists.push(newList); + + return this.updateBoard(); + + } + + removeList(listId) + { + const list = this.board.lists.find((_list) => { + return _list.id === listId; + }); + + for ( const cardId of list.idCards ) + { + this.removeCard(cardId); + } + + const index = this.board.lists.indexOf(list); + + this.board.lists.splice(index, 1); + + return this.updateBoard(); + } + + removeCard(cardId, listId?) + { + + const card = this.board.cards.find((_card) => { + return _card.id === cardId; + }); + + if ( listId ) + { + const list = this.board.lists.find((_list) => { + return listId === _list.id; + }); + list.idCards.splice(list.idCards.indexOf(cardId), 1); + } + + this.board.cards.splice(this.board.cards.indexOf(card), 1); + + this.updateBoard(); + } + + updateBoard() + { + return new Promise((resolve, reject) => { + this.http.post('api/scrumboard-boards/' + this.board.id, this.board) + .subscribe(response => { + this.onBoardChanged.next(this.board); + resolve(this.board); + }, reject); + }); + } + + updateCard(newCard) + { + this.board.cards.map((_card) => { + if ( _card.id === newCard.id ) + { + return newCard; + } + }); + + this.updateBoard(); + } + + createNewBoard(board) + { + return new Promise((resolve, reject) => { + this.http.post('api/scrumboard-boards/' + board.id, board) + .subscribe(response => { + resolve(board); + }, reject); + }); + } +} + +@Injectable() +export class BoardResolve implements Resolve +{ + + constructor(private scrumboardService: ScrumboardService) + { + } + + resolve(route: ActivatedRouteSnapshot) + { + return this.scrumboardService.getBoard(route.paramMap.get('boardId')); + } +} diff --git a/src/app/navigation.model.ts b/src/app/navigation.model.ts index 5aa081be..95191344 100644 --- a/src/app/navigation.model.ts +++ b/src/app/navigation.model.ts @@ -72,6 +72,12 @@ export class FuseNavigation 'fg' : '#FFFFFF' } }, + { + 'title': 'Scrumboard', + 'type' : 'nav-item', + 'icon' : 'assessment', + 'url' : '/apps/scrumboard' + }, { 'title': 'PAGES', 'type' : 'subheader' From 0bf158f8a5fa6bca9fcc09adc950fe01545efc86 Mon Sep 17 00:00:00 2001 From: mustafahlvc Date: Wed, 30 Aug 2017 14:21:14 +0300 Subject: [PATCH 2/8] (Scrumboard) board settings added + some refinements. --- package.json | 135 +++++++++--------- .../board/add-list/add-list.component.ts | 6 +- .../board/dialogs/card/card.component.html | 4 +- .../board/dialogs/card/card.component.ts | 2 +- .../edit-board-name.component.ts | 6 +- .../list/add-card/add-card.component.html | 4 +- .../board/list/add-card/add-card.component.ts | 6 +- .../edit-list-name.component.ts | 6 +- .../scrumboard/board/list/list.component.html | 1 - .../board-color-selector.component.html | 18 ++- .../board-color-selector.component.scss | 10 ++ .../board-color-selector.component.ts | 44 ++++-- .../sidenavs/settings/settings.component.html | 104 ++++++++------ .../sidenavs/settings/settings.component.scss | 31 +++- .../sidenavs/settings/settings.component.ts | 21 +-- .../apps/scrumboard/scrumboard.module.ts | 4 +- .../todo-details/todo-details.component.ts | 6 +- 17 files changed, 255 insertions(+), 153 deletions(-) diff --git a/package.json b/package.json index ebfe1c25..661a44bc 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,70 @@ { - "name": "fuse2", - "version": "1.0.2", - "license": "", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build", - "test": "ng test", - "lint": "ng lint", - "e2e": "ng e2e" - }, - "private": true, - "dependencies": { - "@angular/animations": "4.3.6", - "@angular/cdk": "2.0.0-beta.10", - "@angular/common": "4.3.6", - "@angular/compiler": "4.3.6", - "@angular/core": "4.3.6", - "@angular/flex-layout": "2.0.0-beta.9", - "@angular/forms": "4.3.6", - "@angular/http": "4.3.6", - "@angular/material": "2.0.0-beta.10", - "@angular/platform-browser": "4.3.6", - "@angular/platform-browser-dynamic": "4.3.6", - "@angular/router": "4.3.6", - "@swimlane/ngx-charts": "6.0.2", - "@swimlane/ngx-datatable": "9.3.1", - "@swimlane/ngx-dnd": "3.0.0", - "angular-calendar": "0.19.0", - "angular-in-memory-web-api": "0.3.2", - "classlist.js": "1.1.20150312", - "core-js": "2.5.0", - "d3": "4.10.0", - "hammerjs": "2.0.8", - "highlight.js": "9.12.0", - "intl": "1.2.5", - "moment": "2.18.1", - "ngx-color-picker": "4.3.1", - "ngx-cookie-service": "1.0.7", - "ngx-perfect-scrollbar": "4.5.6", - "rxjs": "5.4.3", - "web-animations-js": "2.3.1", - "zone.js": "0.8.17" - }, - "devDependencies": { - "@angular/cli": "^1.3.2", - "@angular/compiler-cli": "4.3.6", - "@angular/language-service": "4.3.6", - "@ngtools/webpack": "^1.6.2", - "@types/jasmine": "^2.5.54", - "@types/jasminewd2": "^2.0.2", - "@types/node": "^6.0.88", - "codelyzer": "~3.0.1", - "jasmine-core": "~2.6.2", - "jasmine-spec-reporter": "~4.1.0", - "karma": "~1.7.0", - "karma-chrome-launcher": "~2.1.1", - "karma-cli": "~1.0.1", - "karma-coverage-istanbul-reporter": "^1.2.1", - "karma-jasmine": "~1.1.0", - "karma-jasmine-html-reporter": "^0.2.2", - "node-sass": "^4.5.3", - "protractor": "~5.1.2", - "ts-node": "~3.0.4", - "tslint": "~5.3.2", - "typescript": "~2.3.3" - } + "name": "fuse2", + "version": "1.0.2", + "license": "", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e" + }, + "private": true, + "dependencies": { + "@angular/animations": "4.3.6", + "@angular/cdk": "2.0.0-beta.10", + "@angular/common": "4.3.6", + "@angular/compiler": "4.3.6", + "@angular/core": "4.3.6", + "@angular/flex-layout": "2.0.0-beta.9", + "@angular/forms": "4.3.6", + "@angular/http": "4.3.6", + "@angular/material": "2.0.0-beta.10", + "@angular/platform-browser": "4.3.6", + "@angular/platform-browser-dynamic": "4.3.6", + "@angular/router": "4.3.6", + "@swimlane/ngx-charts": "6.0.2", + "@swimlane/ngx-datatable": "9.3.1", + "@swimlane/ngx-dnd": "3.0.0", + "angular-calendar": "0.19.0", + "angular-in-memory-web-api": "0.3.2", + "classlist.js": "1.1.20150312", + "core-js": "2.5.0", + "d3": "4.10.0", + "hammerjs": "2.0.8", + "highlight.js": "9.12.0", + "intl": "1.2.5", + "md2": "0.0.28", + "moment": "2.18.1", + "ngx-color-picker": "4.3.1", + "ngx-cookie-service": "1.0.7", + "ngx-perfect-scrollbar": "4.5.6", + "rxjs": "5.4.3", + "web-animations-js": "2.3.1", + "zone.js": "0.8.17" + }, + "devDependencies": { + "@angular/cli": "^1.3.2", + "@angular/compiler-cli": "4.3.6", + "@angular/language-service": "4.3.6", + "@ngtools/webpack": "^1.6.2", + "@types/jasmine": "^2.5.54", + "@types/jasminewd2": "^2.0.2", + "@types/node": "^6.0.88", + "codelyzer": "~3.0.1", + "jasmine-core": "~2.6.2", + "jasmine-spec-reporter": "~4.1.0", + "karma": "~1.7.0", + "karma-chrome-launcher": "~2.1.1", + "karma-cli": "~1.0.1", + "karma-coverage-istanbul-reporter": "^1.2.1", + "karma-jasmine": "~1.1.0", + "karma-jasmine-html-reporter": "^0.2.2", + "node-sass": "^4.5.3", + "protractor": "~5.1.2", + "ts-node": "~3.0.4", + "tslint": "~5.3.2", + "typescript": "~2.3.3" + } } diff --git a/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts index f0265579..0d7f6713 100644 --- a/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts +++ b/src/app/main/content/apps/scrumboard/board/add-list/add-list.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { Component, EventEmitter, OnInit, Output, ViewChild} from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ @@ -11,7 +11,7 @@ export class FuseScrumboardBoardAddListComponent implements OnInit formActive = false; form: FormGroup; @Output() onlistAdd = new EventEmitter(); - @ViewChildren('nameInput') nameInputField; + @ViewChild('nameInput') nameInputField; constructor( private formBuilder: FormBuilder @@ -41,7 +41,7 @@ export class FuseScrumboardBoardAddListComponent implements OnInit focusNameField() { setTimeout(() => { - this.nameInputField.first.nativeElement.focus(); + this.nameInputField.nativeElement.focus(); }); } diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html index 857cb539..ed1dc068 100644 --- a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.html @@ -74,8 +74,8 @@
- - + + diff --git a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts index 73d8b3eb..050e6403 100644 --- a/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts +++ b/src/app/main/content/apps/scrumboard/board/dialogs/card/card.component.ts @@ -213,7 +213,7 @@ export class FuseScrumboardCardDialogComponent implements OnInit, OnDestroy onChecklistMenuOpen() { setTimeout(() => { - this.newCheckListTitleField._mdInputChild.focus(); + this.newCheckListTitleField.nativeElement.focus(); }); } diff --git a/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts index ddcbf583..d35face2 100644 --- a/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts +++ b/src/app/main/content/apps/scrumboard/board/edit-board-name/edit-board-name.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ @@ -12,7 +12,7 @@ export class FuseScrumboardEditBoardNameComponent implements OnInit form: FormGroup; @Input() board; @Output() onNameChanged = new EventEmitter(); - @ViewChildren('nameInput') nameInputField; + @ViewChild('nameInput') nameInputField; constructor( private formBuilder: FormBuilder @@ -42,7 +42,7 @@ export class FuseScrumboardEditBoardNameComponent implements OnInit focusNameField() { setTimeout(() => { - this.nameInputField.first.nativeElement.focus(); + this.nameInputField.nativeElement.focus(); }); } diff --git a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html index 74a65988..82c4bdbd 100644 --- a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html +++ b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.html @@ -11,8 +11,8 @@ - - + +
diff --git a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts index 977f1fd3..053b80bc 100644 --- a/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts +++ b/src/app/main/content/apps/scrumboard/board/list/add-card/add-card.component.ts @@ -1,4 +1,4 @@ -import { Component, ContentChildren, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ @@ -11,7 +11,7 @@ export class FuseScrumboardBoardAddCardComponent implements OnInit formActive = false; form: FormGroup; @Output() onCardAdd = new EventEmitter(); - @ViewChildren('nameInput') nameInputField; + @ViewChild('nameInput') nameInputField; constructor( private formBuilder: FormBuilder @@ -40,7 +40,7 @@ export class FuseScrumboardBoardAddCardComponent implements OnInit focusNameField() { setTimeout(() => { - this.nameInputField.first._mdInputChild.focus(); + this.nameInputField.nativeElement.focus(); }); } diff --git a/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts index bb2cc7b2..f480c7cd 100644 --- a/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts +++ b/src/app/main/content/apps/scrumboard/board/list/edit-list-name/edit-list-name.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChildren } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ @@ -12,7 +12,7 @@ export class FuseScrumboardBoardEditListNameComponent implements OnInit form: FormGroup; @Input() list; @Output() onNameChanged = new EventEmitter(); - @ViewChildren('nameInput') nameInputField; + @ViewChild('nameInput') nameInputField; constructor( private formBuilder: FormBuilder @@ -42,7 +42,7 @@ export class FuseScrumboardBoardEditListNameComponent implements OnInit focusNameField() { setTimeout(() => { - this.nameInputField.first.nativeElement.focus(); + this.nameInputField.nativeElement.focus(); }); } diff --git a/src/app/main/content/apps/scrumboard/board/list/list.component.html b/src/app/main/content/apps/scrumboard/board/list/list.component.html index ae544bd8..910a01cc 100644 --- a/src/app/main/content/apps/scrumboard/board/list/list.component.html +++ b/src/app/main/content/apps/scrumboard/board/list/list.component.html @@ -40,7 +40,6 @@ diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.html b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.html index 07c277d7..678dbf0d 100644 --- a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.html +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.html @@ -1,3 +1,15 @@ -

- board-color-selector works! -

+ + + +

{{color.key}}

+ check + +
+ +
diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.scss b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.scss index e69de29b..d6b3d042 100644 --- a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.scss +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.scss @@ -0,0 +1,10 @@ +:host { + + .colors { + + .color { + position: relative; + cursor: pointer; + } + } +} diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts index bf9ff816..c4a4195d 100644 --- a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/board-color-selector/board-color-selector.component.ts @@ -1,15 +1,43 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { MatColors } from '../../../../../../../../core/matColors'; +import { ScrumboardService } from '../../../../scrumboard.service'; +import { Subscription } from 'rxjs/Subscription'; @Component({ - selector: 'app-board-color-selector', - templateUrl: './board-color-selector.component.html', - styleUrls: ['./board-color-selector.component.scss'] + selector : 'fuse-scrumboard-board-color-selector', + templateUrl: './board-color-selector.component.html', + styleUrls : ['./board-color-selector.component.scss'] }) -export class BoardColorSelectorComponent implements OnInit { +export class FuseScrumboardBoardColorSelectorComponent implements OnInit, OnDestroy +{ + colors: any; + board: any; + onBoardChanged: Subscription; - constructor() { } + constructor( + private scrumboardService: ScrumboardService + ) + { + this.colors = MatColors.all; + } - ngOnInit() { - } + ngOnInit() + { + this.onBoardChanged = + this.scrumboardService.onBoardChanged + .subscribe(board => { + this.board = board; + }); + } + setColor(color) + { + this.board.settings.color = color; + this.scrumboardService.updateBoard(); + } + + ngOnDestroy() + { + this.onBoardChanged.unsubscribe(); + } } diff --git a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html index 47485e4b..df4304e2 100644 --- a/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html +++ b/src/app/main/content/apps/scrumboard/board/sidenavs/settings/settings.component.html @@ -1,52 +1,76 @@ - -
-
Settings
-
- +
- -
+
-