mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
1.6.0 (#2029)
* fix upload area snackbar behaviour * SASS support for components ability to use '.scss' files from within components * [ADF-610] Upload button and DnD area should not upload hidden files and folders (#1908) [ADF-610] upload cleanup - more strongly typing - api improvements * Upload cleanup and api improvements - remove old unused settings (formFields variable) - individual options for uploaded files (i.e. versioning) - upload button and drag-and-drop area now set individual settings for file versioning * exclude hidden files from upload * [ADF-640] reload document list on folder upload (#1895) * reload document list on folder upload - extend UploadService with 'folderCreated' event to be able reacting on folder uploads globally - extend Demo Shell to reload document list on UploadService events (folderCreated) * readme updates * [ADF-621] show drop effect on folders only (#1897) * show drop effect on folders only - fix `hasValue` api for data rows (avoid 'false' value to be evaluated as missing value) - support for evaluating drop support for rows - document list enables upload zones for folders only * api improvements as per code review * [ADF-242] Fixed behaviour for saving/deleting reports (#1905) * [ADF-242] - fix for deleting - saving a report * [ADF - 242] added test for fixed feature on reports save - delete * Added translation key * [ADF-604] Upgrade @angular/material to latest version (#1909) * update dependencies and module imports * fix template warnings and fix import issues * migrate Activiti Form to MdTabsModule * fix unit tests * fix tests * fix unit tests * fix unit tests * disable test that fails only on travis * upgrade activiti form component to angular/material * fix test (remove MDL class check) * [ADF-613] Add plain text viewer (#1873) * add plain text viewer * different devices optimizations * returns types * [ADF-573] support for toggling enabled state (#1912) * [ADF-602] Accordion component - Add basic documentation (#1913) * Add basic documentation Accordion component * Update README.md * [ADF-680] Added previous page check when page has no more elements (#1911) * [ADF-242] - fix for deleting - saving a report * [ADF - 242] added test for fixed feature on reports save - delete * [ADF-680] - Fixed behaviour when deleting all files on last page of document list * Start adding test for documentlist check * Added test for check double page load * [ADF-680] - removed commented test code * [ADF-680] Added changes from peer review * [ADF-680] added return type * [ADF-667] selection mode and row styles (#1914) * selection mode and row styles - single/multiple/none selection modes for DataTable component (and Document List) - support for custom row styles (inline and classname values) - fix karma config (material themes) - readme updates - package-lock.json files for NPM5 support - updated DataTable demo to demonstrate selection modes and row styles * remove package lock files * move demo projects to webpack (#1915) * wav and Mp3 enabling viewer (#1916) * add option only demo shell version change for update version script * ADF-402 add the show diagram button (#1917) * [ADF-707] Ability to select a row on a dynamic table (#1921) * [ADF-710] Create an Process Attachment List component (#1919) * added new component to list the process attachments with view, download and delete functionality * added unit test cases for activit-process-attachment-list component * exported new process attachment list component * added documentation for process-attachment-list component * [ADF-712] Task Attachment - Provide a way to attach a new content (#1898) * create button, download, view functionality added in task attachment list component * created sevice to attach document to task * added new component to create/uplaod attachment to task * added new component to create/uplaod attachment to task * added test case for create task attachment component * added test case for create task attachment component * added input to block upload document to ECM * fixed create task attachment spec file issue * changed alfresco-upload to alfresco-core upload directive * removed attachCreate button and emitter from task-attachment-list * removed uploadToEcm input and checkValidity method from alfresco-upload * added documentation for task-attachment-list and create-task-attachment components * [ADF-696] Entire accordion group header should be clickable (#1918) * #ADF-696 Added new input to show/hide expand icon, click event is activated for the complete heading * #ADF-696 tslint fix * #ADF-696 Added documentation for new input and removed unwanted div * [ADF-721] Fix translation reference for dev task (#1923) * move translation files in the bundles folder * fix after review ripristinate tslint and remove override tsconfig * [ADF-709] add autofocus when a new row is added on dynamic table widget (#1927) * [ADF-709] add autofocus when a new row is added on dynamic table widget * [ADF-709] removed wrong reference for template * [ADF-713] Process Attachment - Provide a way to attach a new content (#1920) * added service to get all the related content of the process instance * added new component to create/upload attachment for process instance * added unit test cases for create-process-attachment component * exported create-process-attachment component * added documentation for create-process-attachment component * Add data-automation-id to multi select checkbox (#1924) * [ADF-571] upload feature rework (#1922) * upload feature rework lots of improvements for upload dialog and underlying services * readme update - readme cleanup - remove some old comments from code - update readme with new events for Upload Service * restore prerequisites section in readme * fix i18n issue with webpack * exported report and chart models (#1925) * fix file upload bug (#1928) - proper extraction of File objects from the FileList * lock files for npm 5 (#1930) add lock files for npm v5; does nothing for earlier versions, so is not harmful * Source Mapping is not working on test debugging (#1931) * coverage single components run fix * remove spec.ts from coverage * make the coverage and the istanbul-instrumenter-loader works only over the console test because a problem on the remapping for the browser test * move tslint on the main folder of any component * remove build:w from readme * stop build tslint error also in spec files * clear karma file from unnecessary files * add set -f for build all script in order to accept * * fix lint problem and failing tests * fix failing test search component * add loader test for viewer * fix tslint error userinfo * --max_old_space_size=2048 remove * fix tslint error uploader unused EventEmitter * remove spec|index|.*mock|.*model|.*event from coverage * move coverage separate file and get component to calculate coverage as input * remove old 'banned' demo from login screen (#1929) * add sleep time flag in publish script * rollback demo tag * fix pacakge.json tag * [ADF-686] add blobFile as input (#1933) * coverage fix (#1934) * [ADF-702] Task/Process Filter - Provide a way to change the default filter (#1932) * [ADF-702] Task/Process Filter - Provide a way to change the default filter * Provide a way to select a custom menu filter * Improve activiti process filter * Add internal link * Change link name * add link * [ADF-744] Attachment List is not displayed within Processes. (#1937) * Use the adf process attachment list indise demo shell * Change documentation * support for healdess chrome (#1939) * #ADF-696 Now accordion opens/closes on click of group header along with emitting heading click event (#1936) * add info and link on current last git commit (#1940) * [ADF-754] toolbar component (#1938) * toolbar component - simple toolbar component (core lib) - readme updates (core lib) - update demo shell with toolbar component demo (document list) * update unit tests * [ADF-763] Add Chrome default browser for karma chrome launcher for Chrome versi… (#1941) * Add Chrome default browser for karma chrome launcher for Chrome version<59 * Fixing intermittently failing test in ng2-activiti-analytics component * Adding new icon (sent) for Bootstrap to Material icon mapping (#1943) * fix blob input in text viewer (#1942) * GitHub issue & pull request template change (#1945) * Update ISSUE_TEMPLATE.md * Update PULL_REQUEST_TEMPLATE.md * [ADF-689] Fix alfresco-document-menu-action styling (z-index) (#1944) * fix translation wrong folder creation issue * [ADF-773] Fix datatable custom template render (#1947) * [ADF-780] centralised call for process filters api (#1950) * [ADF-780] centralised call for process filters api * [ADF-780] updated conversion to string * [ADF-741] Add the create task attachment component to the demo shell (#1946) * Add the create task attachment component to the demo shell * Add translation keys * Add return to methods * fix thumbnail task process list (#1951) * [ADF-643] upload enhancements (#1949) * rework folder uploading - flatterns hierarchy on folder upload - performs a single traversal for the entire folder heirarchy and ends with a comple file list - allows now dropping folders on existing folders - overall code improvements * fix unit tests * readme updates * clean old and unused code * code cleanup * limit concurrent uploads * update code as per review * fix upload button for Safari * fixes for Safari - Safari compatibility - code updates based on review * fix code * fix unit tests * [ADF-589] Login component different bug fixes (#1953) * Basic style changes * Further design changes * Responsive design fixes * Different sign in button style for the different login steps * #ADF-780 Fixed getProcessFilterByName to get the correct filter for the given appId and name (#1952) * fix issues with the require keyword (angular cli) (#1954) * [ADF-799] add HappyPack to webpack conf (#1956) * update npm5 lock files * [ADF-740] Add button for process attachment list (#1955) * [ADF-740] adding button to allow user to upload related content on process instance * [ADF-740] add button for attachment content list for process * changed locatin for translation * [ADF-740] added test for add button for process attach * [ADF-740] added PR request changes * [ADF-802] fix error on uploading file to attachment list (#1957) * [ADF-802] fix error on uploading file to attachment list * [ADF-802] improved for loop * [ADF-797] remove dist folder from npm distributed package , leave src and bundles (#1961) * [ADF-804] webpack proxy setup to avoid CORS problem (#1960) * package lock update * update travis to node 8 (#1965) * upload service exposes created nodes (#1964) * [ADF-591] documentation refinements (#1959) * refine ng2-activiti-analytics * refine ng2-activiti-diagrams docs * refine ng2-activiti-form * refine ng2-activiti-processlist * refine ng2-activiti-tasklist * refine ng2-alfresco-core * refine ng2-alfresco-datatable * refine ng2-alfresco-datatable * refine gn2-alfresco-login * refine ng2-alfresco-search * refine ng2-alfresco-social * refine ng2-alfresco-tag * refine ng2-alfresco-upload * refine ng2-alfresco-userinfo * refine ng2-alfresco-viewer * refine ng2-alfresco-webscript * various readme cleanups * fix builds related to node-sass library (#1966) * update dependencies and remove old lock files * update sass loader * updated lock files * [ADF-578] Remember me functionality (#1962) * Remember me functionality * Happy pack to ng2-components' package.json * Build fix * Adding tabindices to viewer control elements (#1968) * karma conf all single browser * Fix current page number issue (#1970) * [ADF-524] Datatable loading state (#1958) * loading state datatable * modify readme after review * [ADF-78] Update CORS help (#1973) * Fix host configuration in demo-shell when no port is present (#1971) * remove brachet * [ADF-494] fixed readonly rendering for forms (#1972) * [ADF-494] improved disabling for form * [ADF-494] fixed readonly rendering for forms * [ADF-814] application configuration service (#1969) * app configuration service * api improvements and readme update * extend readme and add defaults * unit tests for app config service * [ADF-716] Task Header - Use a custom view inside the component (#1967) * Use a generic custom view inside the task header * Move the component into core component and change name * Missing file * Fix unit test * fix unit test component name * fix issue with shared Code settings - remove obsolete rules for .js/.ts - hide .happypack folder in the project tree * [ADF-810] fix default value radio button (#1975) * [ADF-510] Drag&Drop check permission to allow user to upload a file (#1948) * [ADF-510] added permission check for drag&drop * Improved code for drag and drop side * Added test for drag and drop upload area changes * Added test for document list permissions check * [ADF-510] rebased branch after changes applied to upload * [ADF-510] rebased branch and fixed tests * [ADF-717] upgrade i18n and charting dependencies (#1976) * remove app-specific polyfill dependencies remove polyfill dependencies never used by component libraries * upgrade i18n dependencies * upgrade ng2-charts dependency * fix unit tests * update demo projects * [ADF-524] Fix empty state after the loading introduction (#1980) * fix empty state after the loading introduction * Update document-list.component.spec.ts remove typo * [ADF-838] Table of content automatic creation (#1981) * readonly value set * Table of content automatic creation (#1982) * add missing intl dependency for demo shell (#1984) * [ADF-833] DataTable - improve the single and double click event (#1979) * Improve the single and double click event * Fix unit test * Task header basic documentation (#1985) * Disable upload attachment when the task is completed (#1987) * [ADF-847] upgrade to use application configuration service (#1986) * migrate core lib to use server-side app config * fix unit tests * update Search tests - update tests - upgrade tests to use TestBed * update UserInfo tests * update Social tests * update tests * update unit tests * cleanup old code * update about page * update demo shell readme * dev and prod configurations * updated package-lock file and removed duplicates in package.json * [ADF-851] execute-outcome event for form service (#1989) * execute-outcome event for form service * readme updates * fix loading state excluding other state during the loading (#1991) * Fix compilation error (#1993) * [ADF-883] Fix build errors (#1992) * [ADF-793] Ability to create PDF renditions in case of non supported formats (#1994) * Style changes and button * Convert to PDF button * Convert to PDF button part II. * Convert within the Not Supported Format component * Rendition loading skeleton * Conversion is working. * Convert button behaviour tests * Rebasing fix. * app settings page (#1997) - custom app setttings service to use isolated storage (demo shell) - restore settings UI - redirect angular and rxjs to the same version as components use. * [ADF-822] Added the npm-prepublish script (#1978) * added the npm prepublish script * changed permissions to prepublish script * changed to npm run prepublish * prepare the pr * removed useless code to the script * remove flags lib from demo shell (#1983) * remove flags lib from demo shell greatly reduce demo shell webpack resources by switching off flags (only 3 icons were displayed in the past) * merge package.json * add icons * Fix typo error * [ADF-794] Add people assignment component (#1977) * Add people component * exported people service * added people-list component to show the involved user list * changed people-search component layout * changed people-list usage in people component * changed people-list data table from custom template to data adapter * changes people-search component related to people-list * changes in activiti-people related to people-list and people-search component * changed data adapter to direct data column setting to data-table * removed ngChanges and added User and UserEvent models * added User and UserEvent model in emitter and other emitter handler * added user event model * changed activiti-people component with latest UX changes * addedand changed translate keys to the components * added hasUser method to check the condition in html * fixed tslint issue and test case issue in activiti-people component * added test case for actviti-people-list component * test case added for activiti-people-search component * changed activiti-people test cases according to latest UX changes * added description for activiti-people component * changed test case to fix component.upgradeElement issue * changes requested by Vito Albano #1 * splitted getDisplayUser into getDisplayUser and getInitialUsername * introduce check type definition * [ADF-897] - ActivitiPeopleList - use the adf prefix (#2001) * Use the adf as prexif instead of activiti * Fix typo * Fix wrong import * support binding [form] data directly (#1996) - ability to bind [form] data directly inside `<activiti-form>` component - ability to parse forms with FormService - demo of the custom form in demo shell * [ADF-778] cancel window for upload dialog shows only on complete (#2003) * [ADF-778] Added new behaviour to upload dialog * [ADF-778] cancel window for upload dialog shows only on complete * [ADF-778] changed variable name to showCloseButton * Create task/process attachment Compilation error (#2004) * fix tslint errors minor fix for "Unnecessary semicolon" TSLint rule * [ADF-842] Fixed type for taskdetails (#2009) * fix type definition (#2002) * Use the activiti people with the new look and feel inside the demo shell (#2008) * add rxjs and @angular in tsconfig.json * [ADF-843] Form events bus (#1990) * form events bus * event test bus fix * fix test after code review * fix types errors * change to public formservice * make optional formservice * [ADF-915] Add option to change the JS-API with different version in the update package * Missing keys (#2011) * [ADF-845] breadcrumb root option added and style review (#1999) * breadcrumb root option added and style review * new breadcrumbs * split onchange in a method * update readme with a note for old pefix tag * fix tslint errors * fix breadcrumb test * [ADF-922] Regenerate package-lock.json files for every package and create script for doing that in the future (#2012) * Updated package-lock.json files * npm-relock-pkgs.sh * Update README.md * Fix ng2-alfresco-search sass problem * SASS version update (#2013) * sass update * update sass loader * vjsapi option prepublish * prepublish script deprecation in favour of prepublishOnly node 8 (#2010) * modify prePublish script with preoPublishOnly * install rimraf globally * fix clean scripts demo folders * move appveyor to node 8 * Appveyor test (#1998) * reduce memory * remove max-old-space * remove increase memory * create new TaskDetailsModel in loadNextTask (#2017) * Fix readme document list * [ADF-907] - Form reacts to data added in input (#2016) * [ADF-907] Enable activiti form to react on value data changes * [ADF-907] - Form reacts to data added in input] * [ADF - 907] added mock json for form * [ADF-907] added new event of the form to the event list * [ADF - 907] Added return column to README * [ADF - 907] Added return column to README * Script add pkg and clean update * install globally pkg pre build * Fix upload related content (#2019) * regeneration TOC and add automatic list component generator (#2022) * Fix upload process attachment (#2024) * update typescript (#2026) * update viewer readme * fix type definition variables * NgZone type passed parameter * fix tslint error in tasklist * Add screenshot (#2028) * fix search miss typing * bump version 1.6.0 (#2027)
This commit is contained in:
@@ -26,11 +26,20 @@
|
||||
|
||||
/* Empty folder */
|
||||
|
||||
:host .no-content-container {
|
||||
:host .adf-no-content-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
:host .no-content-container > img {
|
||||
:host .adf-no-content-container > img {
|
||||
width: 100%;
|
||||
}
|
||||
/* Loading folder */
|
||||
|
||||
:host .adf-loading-content-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
:host .adf-loading-content-container > img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -109,11 +118,15 @@
|
||||
}
|
||||
|
||||
.alfresco-datatable__row:focus {
|
||||
outline-offset: -4px;
|
||||
outline-offset: -1px;
|
||||
outline-width: 1px;
|
||||
outline-color: rgb(68,138,255);
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.alfresco-datatable__row--selected {
|
||||
color: rgb(68,138,255);
|
||||
.alfresco-datatable__row--selected,
|
||||
.alfresco-datatable__row--selected:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.adf-upload__dragging > td {
|
||||
|
@@ -29,95 +29,112 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr *ngFor="let row of data.getRows(); let idx = index" tabindex="0"
|
||||
class="alfresco-datatable__row"
|
||||
[class.alfresco-datatable__row--selected]="selectedRow === row"
|
||||
[adf-upload]="allowDropFiles" [adf-upload-data]="row">
|
||||
<ng-container *ngIf="!loading">
|
||||
<tr *ngFor="let row of data.getRows(); let idx = index" tabindex="0"
|
||||
class="alfresco-datatable__row"
|
||||
[class.alfresco-datatable__row--selected]="row.isSelected"
|
||||
[adf-upload]="allowDropFiles && rowAllowsDrop(row)" [adf-upload-data]="row"
|
||||
[ngStyle]="rowStyle"
|
||||
[ngClass]="rowStyleClass">
|
||||
|
||||
<!-- Actions (left) -->
|
||||
<td *ngIf="actions && actionsPosition === 'left'" class="alfresco-datatable__actions-cell">
|
||||
<button [id]="'action_menu_' + idx" alfresco-mdl-button class="mdl-button--icon" [attr.data-automation-id]="actions_menu">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-left"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
{{action.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<!-- Actions (left) -->
|
||||
<td *ngIf="actions && actionsPosition === 'left'" class="alfresco-datatable__actions-cell">
|
||||
<button [id]="'action_menu_' + idx" alfresco-mdl-button class="mdl-button--icon"
|
||||
[attr.data-automation-id]="actions_menu">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-left"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
{{action.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
<td *ngIf="multiselect">
|
||||
<md-checkbox [(ngModel)]="row.isSelected"></md-checkbox>
|
||||
</td>
|
||||
<td *ngFor="let col of data.getColumns()"
|
||||
class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}"
|
||||
(click)="onRowClick(row, $event)"
|
||||
(dblclick)="onRowDblClick(row, $event)"
|
||||
[context-menu]="getContextMenuActions(row, col)"
|
||||
[context-menu-enabled]="contextMenu">
|
||||
<div *ngIf="!col.template" class="cell-container">
|
||||
<ng-container [ngSwitch]="col.type">
|
||||
<div *ngSwitchCase="'image'" class="cell-value">
|
||||
<i *ngIf="isIconValue(row, col)" class="material-icons icon-cell">{{asIconValue(row, col)}}</i>
|
||||
<img *ngIf="!isIconValue(row, col)"
|
||||
class="image-cell"
|
||||
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
|
||||
src="{{ data.getValue(row, col) }}"
|
||||
(error)="onImageLoadingError($event)">
|
||||
</div>
|
||||
<div *ngSwitchCase="'icon'" class="cell-value">
|
||||
<img class="image-cell"
|
||||
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
|
||||
src="{{ data.getValue(row, col) }}"
|
||||
(error)="onImageLoadingError($event)">
|
||||
</div>
|
||||
<div *ngSwitchCase="'date'" class="cell-value" [attr.data-automation-id]="'date_' + data.getValue(row, col)">
|
||||
<alfresco-datatable-cell [data]="data" [column]="col" [row]="row"></alfresco-datatable-cell>
|
||||
</div>
|
||||
<div *ngSwitchCase="'text'" class="cell-value" [attr.data-automation-id]="'text_' + data.getValue(row, col)">
|
||||
<alfresco-datatable-cell [data]="data" [column]="col" [row]="row"></alfresco-datatable-cell>
|
||||
</div>
|
||||
<td *ngIf="multiselect">
|
||||
<md-checkbox [(ngModel)]="row.isSelected"></md-checkbox>
|
||||
</td>
|
||||
<td *ngFor="let col of data.getColumns()"
|
||||
class="mdl-data-table__cell--non-numeric non-selectable data-cell {{col.cssClass}}"
|
||||
(click)="onRowClick(row, $event)"
|
||||
[context-menu]="getContextMenuActions(row, col)"
|
||||
[context-menu-enabled]="contextMenu">
|
||||
<div *ngIf="!col.template" class="cell-container">
|
||||
<ng-container [ngSwitch]="col.type">
|
||||
<div *ngSwitchCase="'image'" class="cell-value">
|
||||
<i *ngIf="isIconValue(row, col)" class="material-icons icon-cell">{{asIconValue(row,
|
||||
col)}}</i>
|
||||
<img *ngIf="!isIconValue(row, col)"
|
||||
class="image-cell"
|
||||
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
|
||||
src="{{ data.getValue(row, col) }}"
|
||||
(error)="onImageLoadingError($event)">
|
||||
</div>
|
||||
<div *ngSwitchCase="'icon'" class="cell-value">
|
||||
<img class="image-cell"
|
||||
alt="{{ iconAltTextKey(data.getValue(row, col)) | translate }}"
|
||||
src="{{ data.getValue(row, col) }}"
|
||||
(error)="onImageLoadingError($event)">
|
||||
</div>
|
||||
<div *ngSwitchCase="'date'" class="cell-value"
|
||||
[attr.data-automation-id]="'date_' + data.getValue(row, col)">
|
||||
<alfresco-datatable-cell [data]="data" [column]="col" [row]="row"></alfresco-datatable-cell>
|
||||
</div>
|
||||
<div *ngSwitchCase="'text'" class="cell-value"
|
||||
[attr.data-automation-id]="'text_' + data.getValue(row, col)">
|
||||
<alfresco-datatable-cell [data]="data" [column]="col" [row]="row"></alfresco-datatable-cell>
|
||||
</div>
|
||||
<span *ngSwitchDefault class="cell-value">
|
||||
<!-- empty cell for unknown column type -->
|
||||
</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div *ngIf="col.template" class="cell-container">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="col.template"
|
||||
[ngOutletContext]="{ $implicit: { data: data, row: row, col: col }, value: data.getValue(row, col) }">
|
||||
</ng-container>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div *ngIf="col.template" class="cell-container">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="col.template"
|
||||
[ngOutletContext]="{ $implicit: { data: data, row: row, col: col }, value: data.getValue(row, col) }">
|
||||
</ng-container>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Actions (right) -->
|
||||
<td *ngIf="actions && actionsPosition === 'right'" class="alfresco-datatable__actions-cell">
|
||||
<button [id]="'action_menu_' + idx" alfresco-mdl-button class="mdl-button--icon" [attr.data-automation-id]="actions_menu">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-right"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled || undefined"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
{{action.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
<!-- Actions (right) -->
|
||||
<td *ngIf="actions && actionsPosition === 'right'" class="alfresco-datatable__actions-cell">
|
||||
<button [id]="'action_menu_' + idx" alfresco-mdl-button class="mdl-button--icon"
|
||||
[attr.data-automation-id]="actions_menu">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<ul alfresco-mdl-menu class="mdl-menu--bottom-right"
|
||||
[attr.for]="'action_menu_' + idx">
|
||||
<li class="mdl-menu__item" [attr.disabled]="action.disabled || undefined"
|
||||
[attr.data-automation-id]="action.title"
|
||||
*ngFor="let action of getRowActions(row)"
|
||||
(click)="onExecuteRowAction(row, action)">
|
||||
{{action.title}}
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr *ngIf="data.getRows().length === 0">
|
||||
<td class="mdl-data-table__cell--non-numeric no-content-container"
|
||||
</tr>
|
||||
<tr *ngIf="data.getRows().length === 0">
|
||||
<td class="mdl-data-table__cell--non-numeric adf-no-content-container"
|
||||
[attr.colspan]="1 + data.getColumns().length">
|
||||
<ng-template *ngIf="noContentTemplate"
|
||||
ngFor [ngForOf]="[data]"
|
||||
[ngForTemplate]="noContentTemplate">
|
||||
</ng-template>
|
||||
</td>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<tr *ngIf="loading">
|
||||
<td class="mdl-data-table__cell--non-numeric adf-loading-content-container"
|
||||
[attr.colspan]="1 + data.getColumns().length">
|
||||
<template *ngIf="noContentTemplate"
|
||||
ngFor [ngForOf]="[data]"
|
||||
[ngForTemplate]="noContentTemplate">
|
||||
</template>
|
||||
<ng-template *ngIf="loadingTemplate"
|
||||
ngFor [ngForOf]="[data]"
|
||||
[ngForTemplate]="loadingTemplate">
|
||||
</ng-template>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@@ -18,7 +18,7 @@
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { CoreModule } from 'ng2-alfresco-core';
|
||||
import { MdCheckboxChange } from '@angular/material';
|
||||
import { MdCheckboxModule, MdCheckboxChange } from '@angular/material';
|
||||
import { DataTableComponent } from './datatable.component';
|
||||
import { DataTableCellComponent } from './datatable-cell.component';
|
||||
import {
|
||||
@@ -39,7 +39,8 @@ describe('DataTable', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot()
|
||||
CoreModule.forRoot(),
|
||||
MdCheckboxModule
|
||||
],
|
||||
declarations: [
|
||||
DataTableCellComponent,
|
||||
@@ -52,7 +53,6 @@ describe('DataTable', () => {
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
element = fixture.debugElement.nativeElement;
|
||||
//fixture.detectChanges();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -66,6 +66,95 @@ describe('DataTable', () => {
|
||||
};
|
||||
});
|
||||
|
||||
it('should reset selection on mode change', () => {
|
||||
spyOn(dataTable, 'resetSelection').and.callThrough();
|
||||
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[
|
||||
{ name: '1' },
|
||||
{ name: '2' }
|
||||
],
|
||||
[ new ObjectDataColumn({ key: 'name'}) ]
|
||||
);
|
||||
const rows = dataTable.data.getRows();
|
||||
rows[0].isSelected = true;
|
||||
rows[1].isSelected = true;
|
||||
|
||||
expect(rows[0].isSelected).toBeTruthy();
|
||||
expect(rows[1].isSelected).toBeTruthy();
|
||||
|
||||
dataTable.ngOnChanges({
|
||||
selectionMode: new SimpleChange(null, 'multiple', false)
|
||||
});
|
||||
|
||||
expect(dataTable.resetSelection).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should select only one row with [single] selection mode', () => {
|
||||
dataTable.selectionMode = 'single';
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[
|
||||
{ name: '1' },
|
||||
{ name: '2' }
|
||||
],
|
||||
[ new ObjectDataColumn({ key: 'name'}) ]
|
||||
);
|
||||
const rows = dataTable.data.getRows();
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(rows[0], null);
|
||||
expect(rows[0].isSelected).toBeTruthy();
|
||||
expect(rows[1].isSelected).toBeFalsy();
|
||||
|
||||
dataTable.onRowClick(rows[1], null);
|
||||
expect(rows[0].isSelected).toBeFalsy();
|
||||
expect(rows[1].isSelected).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should unselect the row with [single] selection mode', () => {
|
||||
dataTable.selectionMode = 'single';
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[
|
||||
{ name: '1' },
|
||||
{ name: '2' }
|
||||
],
|
||||
[ new ObjectDataColumn({ key: 'name'}) ]
|
||||
);
|
||||
const rows = dataTable.data.getRows();
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(rows[0], null);
|
||||
expect(rows[0].isSelected).toBeTruthy();
|
||||
expect(rows[1].isSelected).toBeFalsy();
|
||||
|
||||
dataTable.onRowClick(rows[0], null);
|
||||
expect(rows[0].isSelected).toBeFalsy();
|
||||
expect(rows[1].isSelected).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should select multiple rows with [multiple] selection mode', () => {
|
||||
dataTable.selectionMode = 'multiple';
|
||||
dataTable.data = new ObjectDataTableAdapter(
|
||||
[
|
||||
{ name: '1' },
|
||||
{ name: '2' }
|
||||
],
|
||||
[ new ObjectDataColumn({ key: 'name'}) ]
|
||||
);
|
||||
const rows = dataTable.data.getRows();
|
||||
|
||||
const event = new MouseEvent('click', {
|
||||
metaKey: true
|
||||
});
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(rows[0], event);
|
||||
dataTable.onRowClick(rows[1], event);
|
||||
|
||||
expect(rows[0].isSelected).toBeTruthy();
|
||||
expect(rows[1].isSelected).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should put actions menu to the right by default', () => {
|
||||
dataTable.data = new ObjectDataTableAdapter([], [
|
||||
<DataColumn> {},
|
||||
@@ -98,7 +187,7 @@ describe('DataTable', () => {
|
||||
it('should initialize default adapter', () => {
|
||||
let table = new DataTableComponent(null);
|
||||
expect(table.data).toBeUndefined();
|
||||
table.ngAfterContentInit();
|
||||
table.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
expect(table.data).toEqual(jasmine.any(ObjectDataTableAdapter));
|
||||
});
|
||||
|
||||
@@ -126,18 +215,65 @@ describe('DataTable', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(row, null);
|
||||
});
|
||||
|
||||
it('should emit row double-click event', done => {
|
||||
let row = <DataRow> {};
|
||||
it('should emit double click if there are two single click in 250ms', (done) => {
|
||||
|
||||
dataTable.rowDblClick.subscribe(e => {
|
||||
expect(e.value).toBe(row);
|
||||
let row = <DataRow> {};
|
||||
dataTable.ngOnChanges({});
|
||||
|
||||
dataTable.rowDblClick.subscribe( () => {
|
||||
done();
|
||||
});
|
||||
|
||||
dataTable.onRowDblClick(row, null);
|
||||
dataTable.onRowClick(row, null);
|
||||
setTimeout(() => {
|
||||
dataTable.onRowClick(row, null);
|
||||
}
|
||||
, 240);
|
||||
|
||||
});
|
||||
|
||||
it('should emit double click if there are more than two single click in 250ms', (done) => {
|
||||
|
||||
let row = <DataRow> {};
|
||||
dataTable.ngOnChanges({});
|
||||
|
||||
dataTable.rowDblClick.subscribe( () => {
|
||||
done();
|
||||
});
|
||||
|
||||
dataTable.onRowClick(row, null);
|
||||
setTimeout(() => {
|
||||
|
||||
dataTable.onRowClick(row, null);
|
||||
dataTable.onRowClick(row, null);
|
||||
}
|
||||
, 240);
|
||||
|
||||
});
|
||||
|
||||
it('should emit single click if there are two single click in more than 250ms', (done) => {
|
||||
|
||||
let row = <DataRow> {};
|
||||
let clickCount = 0;
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
|
||||
dataTable.rowClick.subscribe( () => {
|
||||
clickCount += 1;
|
||||
if (clickCount === 2) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
dataTable.onRowClick(row, null);
|
||||
setTimeout(() => {
|
||||
dataTable.onRowClick(row, null);
|
||||
}
|
||||
, 260);
|
||||
});
|
||||
|
||||
it('should emit row-click dom event', (done) => {
|
||||
@@ -148,6 +284,7 @@ describe('DataTable', () => {
|
||||
done();
|
||||
});
|
||||
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(row, null);
|
||||
});
|
||||
|
||||
@@ -158,8 +295,9 @@ describe('DataTable', () => {
|
||||
expect(e.detail.value).toBe(row);
|
||||
done();
|
||||
});
|
||||
|
||||
dataTable.onRowDblClick(row, null);
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.onRowClick(row, null);
|
||||
dataTable.onRowClick(row, null);
|
||||
});
|
||||
|
||||
it('should prevent default behaviour on row click event', () => {
|
||||
@@ -171,13 +309,14 @@ describe('DataTable', () => {
|
||||
|
||||
it('should prevent default behaviour on row double-click event', () => {
|
||||
let e = jasmine.createSpyObj('event', ['preventDefault']);
|
||||
dataTable.ngOnChanges({});
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.onRowDblClick(null, e);
|
||||
expect(e.preventDefault).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not sort if column is missing', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
let adapter = dataTable.data;
|
||||
spyOn(adapter, 'setSorting').and.callThrough();
|
||||
dataTable.onColumnHeaderClick(null);
|
||||
@@ -185,7 +324,7 @@ describe('DataTable', () => {
|
||||
});
|
||||
|
||||
it('should not sort upon clicking non-sortable column header', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
let adapter = dataTable.data;
|
||||
spyOn(adapter, 'setSorting').and.callThrough();
|
||||
|
||||
@@ -198,7 +337,7 @@ describe('DataTable', () => {
|
||||
});
|
||||
|
||||
it('should set sorting upon column header clicked', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
let adapter = dataTable.data;
|
||||
spyOn(adapter, 'setSorting').and.callThrough();
|
||||
|
||||
@@ -217,7 +356,7 @@ describe('DataTable', () => {
|
||||
});
|
||||
|
||||
it('should invert sorting upon column header clicked', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
|
||||
let adapter = dataTable.data;
|
||||
let sorting = new DataSorting('column_1', 'asc');
|
||||
@@ -294,7 +433,7 @@ describe('DataTable', () => {
|
||||
|
||||
it('should allow "select all" calls with no rows', () => {
|
||||
dataTable.multiselect = true;
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
|
||||
dataTable.onSelectAllClick(<MdCheckboxChange> { checked: true });
|
||||
expect(dataTable.isSelectAllChecked).toBe(true);
|
||||
@@ -382,13 +521,13 @@ describe('DataTable', () => {
|
||||
});
|
||||
|
||||
it('should require adapter sorting to evaluate sorting state', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
spyOn(dataTable.data, 'getSorting').and.returnValue(null);
|
||||
expect(dataTable.isColumnSorted(<DataColumn> {}, 'asc')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should evaluate column sorting state', () => {
|
||||
dataTable.ngAfterContentInit();
|
||||
dataTable.ngOnChanges({'data': new SimpleChange('123', {}, true)});
|
||||
spyOn(dataTable.data, 'getSorting').and.returnValue(new DataSorting('column_1', 'asc'));
|
||||
expect(dataTable.isColumnSorted(<DataColumn> {key: 'column_1'}, 'asc')).toBeTruthy();
|
||||
expect(dataTable.isColumnSorted(<DataColumn> {key: 'column_2'}, 'desc')).toBeFalsy();
|
||||
|
@@ -15,25 +15,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Component,
|
||||
OnChanges,
|
||||
SimpleChange,
|
||||
SimpleChanges,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ElementRef,
|
||||
TemplateRef,
|
||||
AfterContentInit,
|
||||
ContentChild,
|
||||
Optional
|
||||
} from '@angular/core';
|
||||
import { Component, OnChanges, SimpleChange, SimpleChanges, Input, Output, EventEmitter, ElementRef, TemplateRef, AfterContentInit, ContentChild, Optional } from '@angular/core';
|
||||
import { DataTableAdapter, DataRow, DataColumn, DataSorting, DataRowEvent, ObjectDataTableAdapter, ObjectDataRow } from '../../data/index';
|
||||
import { DataCellEvent } from './data-cell.event';
|
||||
import { DataRowActionEvent } from './data-row-action.event';
|
||||
import { DataColumnListComponent } from 'ng2-alfresco-core';
|
||||
import { MdCheckboxChange } from '@angular/material';
|
||||
import { Observable, Observer } from 'rxjs/Rx';
|
||||
|
||||
declare var componentHandler;
|
||||
|
||||
@@ -52,6 +40,9 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
@Input()
|
||||
rows: any[] = [];
|
||||
|
||||
@Input()
|
||||
selectionMode: string = 'single'; // none|single|multiple
|
||||
|
||||
@Input()
|
||||
multiselect: boolean = false;
|
||||
|
||||
@@ -70,6 +61,12 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
@Input()
|
||||
allowDropFiles: boolean = false;
|
||||
|
||||
@Input()
|
||||
rowStyle: string;
|
||||
|
||||
@Input()
|
||||
rowStyleClass: string;
|
||||
|
||||
@Output()
|
||||
rowClick: EventEmitter<DataRowEvent> = new EventEmitter<DataRowEvent>();
|
||||
|
||||
@@ -85,32 +82,60 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
@Output()
|
||||
executeRowAction: EventEmitter<DataRowActionEvent> = new EventEmitter<DataRowActionEvent>();
|
||||
|
||||
noContentTemplate: TemplateRef<any>;
|
||||
@Input()
|
||||
loading: boolean = false;
|
||||
|
||||
public noContentTemplate: TemplateRef<any>;
|
||||
public loadingTemplate: TemplateRef<any>;
|
||||
|
||||
isSelectAllChecked: boolean = false;
|
||||
|
||||
get selectedRow(): DataRow {
|
||||
return this.data.selectedRow;
|
||||
}
|
||||
private clickObserver: Observer<DataRowEvent>;
|
||||
private click$: Observable<DataRowEvent>;
|
||||
|
||||
constructor(@Optional() private el: ElementRef) {
|
||||
this.click$ = new Observable<DataRowEvent>(observer => this.clickObserver = observer).share();
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
this.loadTable();
|
||||
this.setTableSchema();
|
||||
this.setupMaterialComponents();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.setupMaterialComponents();
|
||||
}
|
||||
|
||||
private setupMaterialComponents(): boolean {
|
||||
// workaround for MDL issues with dynamic components
|
||||
if (componentHandler) {
|
||||
componentHandler.upgradeAllRegistered();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.initAndSubscribeClickStream();
|
||||
if (this.isPropertyChanged(changes['data'])) {
|
||||
this.loadTable();
|
||||
if (this.isTableEmpty()) {
|
||||
this.initTable();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isPropertyChanged(changes['rows'])) {
|
||||
if (this.data) {
|
||||
this.data.setRows(this.convertToRowsData(changes['rows'].currentValue));
|
||||
if (this.isTableEmpty()) {
|
||||
this.initTable();
|
||||
} else {
|
||||
this.setTableRows(changes['rows'].currentValue);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (changes.selectionMode && !changes.selectionMode.isFirstChange()) {
|
||||
this.resetSelection();
|
||||
}
|
||||
}
|
||||
|
||||
isPropertyChanged(property: SimpleChange): boolean {
|
||||
@@ -121,50 +146,107 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
return rows.map(row => new ObjectDataRow(row));
|
||||
}
|
||||
|
||||
loadTable() {
|
||||
private initAndSubscribeClickStream() {
|
||||
let singleClickStream = this.click$
|
||||
.buffer(this.click$.debounceTime(250))
|
||||
.map(list => list)
|
||||
.filter(x => x.length === 1);
|
||||
|
||||
singleClickStream.subscribe((obj: DataRowEvent[]) => {
|
||||
let event: DataRowEvent = obj[0];
|
||||
let el = obj[0].sender.el;
|
||||
this.rowClick.emit(event);
|
||||
if (!event.defaultPrevented && el.nativeElement) {
|
||||
el.nativeElement.dispatchEvent(
|
||||
new CustomEvent('row-click', {
|
||||
detail: event,
|
||||
bubbles: true
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let multiClickStream = this.click$
|
||||
.buffer(this.click$.debounceTime(250))
|
||||
.map(list => list)
|
||||
.filter(x => x.length >= 2);
|
||||
|
||||
multiClickStream.subscribe((obj: DataRowEvent[]) => {
|
||||
let event: DataRowEvent = obj[0];
|
||||
let el = obj[0].sender.el;
|
||||
this.rowDblClick.emit(event);
|
||||
if (!event.defaultPrevented && el.nativeElement) {
|
||||
el.nativeElement.dispatchEvent(
|
||||
new CustomEvent('row-dblclick', {
|
||||
detail: event,
|
||||
bubbles: true
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private initTable() {
|
||||
this.data = new ObjectDataTableAdapter(this.rows, []);
|
||||
}
|
||||
|
||||
isTableEmpty() {
|
||||
return this.data === undefined || this.data === null;
|
||||
}
|
||||
|
||||
private setTableRows(rows) {
|
||||
if (this.data) {
|
||||
this.data.setRows(this.convertToRowsData(rows));
|
||||
}
|
||||
}
|
||||
|
||||
private setTableSchema() {
|
||||
let schema: DataColumn[] = [];
|
||||
|
||||
if (this.columnList && this.columnList.columns) {
|
||||
schema = this.columnList.columns.map(c => <DataColumn> c);
|
||||
}
|
||||
|
||||
if (!this.data) {
|
||||
this.data = new ObjectDataTableAdapter(this.rows, schema);
|
||||
} else {
|
||||
this.setHtmlColumnConfigurationOnObjectAdapter(schema);
|
||||
}
|
||||
|
||||
// workaround for MDL issues with dynamic components
|
||||
if (componentHandler) {
|
||||
componentHandler.upgradeAllRegistered();
|
||||
}
|
||||
}
|
||||
|
||||
private setHtmlColumnConfigurationOnObjectAdapter(schema: DataColumn[]) {
|
||||
if (schema && schema.length > 0) {
|
||||
if (this.data && schema && schema.length > 0) {
|
||||
this.data.setColumns(schema);
|
||||
}
|
||||
}
|
||||
|
||||
onRowClick(row: DataRow, e?: Event) {
|
||||
onRowClick(row: DataRow, e: MouseEvent) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (this.data) {
|
||||
this.data.selectedRow = row;
|
||||
if (row) {
|
||||
if (this.data) {
|
||||
const newValue = !row.isSelected;
|
||||
const rows = this.data.getRows();
|
||||
|
||||
if (this.isSingleSelectionMode()) {
|
||||
rows.forEach(r => r.isSelected = false);
|
||||
row.isSelected = newValue;
|
||||
}
|
||||
|
||||
if (this.isMultiSelectionMode()) {
|
||||
const modifier = e.metaKey || e.ctrlKey;
|
||||
if (!modifier) {
|
||||
rows.forEach(r => r.isSelected = false);
|
||||
}
|
||||
row.isSelected = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
let dataRowEvent = new DataRowEvent(row, e, this);
|
||||
this.clickObserver.next(dataRowEvent);
|
||||
}
|
||||
}
|
||||
|
||||
let event = new DataRowEvent(row, e, this);
|
||||
this.rowClick.emit(event);
|
||||
|
||||
if (!event.defaultPrevented && this.el.nativeElement) {
|
||||
this.el.nativeElement.dispatchEvent(
|
||||
new CustomEvent('row-click', {
|
||||
detail: event,
|
||||
bubbles: true
|
||||
})
|
||||
);
|
||||
resetSelection(): void {
|
||||
if (this.data) {
|
||||
const rows = this.data.getRows();
|
||||
if (rows && rows.length > 0) {
|
||||
rows.forEach(r => r.isSelected = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,18 +254,8 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
let event = new DataRowEvent(row, e, this);
|
||||
this.rowDblClick.emit(event);
|
||||
|
||||
if (!event.defaultPrevented && this.el.nativeElement) {
|
||||
this.el.nativeElement.dispatchEvent(
|
||||
new CustomEvent('row-dblclick', {
|
||||
detail: event,
|
||||
bubbles: true
|
||||
})
|
||||
);
|
||||
}
|
||||
let dataRowEvent = new DataRowEvent(row, e, this);
|
||||
this.clickObserver.next(dataRowEvent);
|
||||
}
|
||||
|
||||
onColumnHeaderClick(column: DataColumn) {
|
||||
@@ -264,4 +336,20 @@ export class DataTableComponent implements AfterContentInit, OnChanges {
|
||||
this.executeRowAction.emit(new DataRowActionEvent(row, action));
|
||||
}
|
||||
}
|
||||
|
||||
rowAllowsDrop(row: DataRow): boolean {
|
||||
return row.isDropTarget === true;
|
||||
}
|
||||
|
||||
hasSelectionMode(): boolean {
|
||||
return this.isSingleSelectionMode() || this.isMultiSelectionMode();
|
||||
}
|
||||
|
||||
isSingleSelectionMode(): boolean {
|
||||
return this.selectionMode && this.selectionMode.toLowerCase() === 'single';
|
||||
}
|
||||
|
||||
isMultiSelectionMode(): boolean {
|
||||
return this.selectionMode && this.selectionMode.toLowerCase() === 'multiple';
|
||||
}
|
||||
}
|
||||
|
@@ -16,5 +16,4 @@
|
||||
*/
|
||||
|
||||
export * from './datatable.component';
|
||||
export * from './no-content-template.component';
|
||||
export * from './datatable-cell.component';
|
||||
|
@@ -32,6 +32,7 @@ export interface DataTableAdapter {
|
||||
|
||||
export interface DataRow {
|
||||
isSelected: boolean;
|
||||
isDropTarget?: boolean;
|
||||
hasValue(key: string): boolean;
|
||||
getValue(key: string): any;
|
||||
}
|
||||
|
@@ -15,10 +15,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TemplateRef } from '@angular/core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { ObjectUtils } from 'ng2-alfresco-core';
|
||||
import { DataTableAdapter, DataRow, DataColumn, DataSorting } from './datatable-adapter';
|
||||
|
||||
declare var require: any;
|
||||
|
||||
// Simple implementation of the DataTableAdapter interface.
|
||||
export class ObjectDataTableAdapter implements DataTableAdapter {
|
||||
|
||||
@@ -196,12 +199,11 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
|
||||
// Simple implementation of the DataRow interface.
|
||||
export class ObjectDataRow implements DataRow {
|
||||
|
||||
isSelected: boolean = false;
|
||||
|
||||
constructor(private obj: any) {
|
||||
constructor(private obj: any, public isSelected: boolean = false) {
|
||||
if (!obj) {
|
||||
throw new Error('Object source not found');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getValue(key: string): any {
|
||||
@@ -209,7 +211,7 @@ export class ObjectDataRow implements DataRow {
|
||||
}
|
||||
|
||||
hasValue(key: string): boolean {
|
||||
return this.getValue(key) ? true : false;
|
||||
return this.getValue(key) !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +224,7 @@ export class ObjectDataColumn implements DataColumn {
|
||||
title: string;
|
||||
srTitle: string;
|
||||
cssClass: string;
|
||||
template?: TemplateRef<any>;
|
||||
|
||||
constructor(obj: any) {
|
||||
this.key = obj.key;
|
||||
@@ -230,5 +233,6 @@ export class ObjectDataColumn implements DataColumn {
|
||||
this.title = obj.title;
|
||||
this.srTitle = obj.srTitle;
|
||||
this.cssClass = obj.cssClass;
|
||||
this.template = obj.template;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,19 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './no-content-template.component';
|
||||
export * from './loading-template.component';
|
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LoadingContentTemplateComponent } from './loading-template.component';
|
||||
import { Injector } from '@angular/core';
|
||||
import { getTestBed, TestBed } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
describe('LoadingContentTemplateComponent', () => {
|
||||
let injector: Injector;
|
||||
let loadingContentTemplateComponent: LoadingContentTemplateComponent;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
LoadingContentTemplateComponent,
|
||||
DataTableComponent
|
||||
]
|
||||
});
|
||||
injector = getTestBed();
|
||||
loadingContentTemplateComponent = injector.get(LoadingContentTemplateComponent);
|
||||
});
|
||||
|
||||
it('is defined', () => {
|
||||
expect(loadingContentTemplateComponent).toBeDefined();
|
||||
});
|
||||
});
|
@@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, ContentChild, TemplateRef, AfterContentInit } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
@Directive({
|
||||
selector: 'loading-content-template'
|
||||
})
|
||||
export class LoadingContentTemplateComponent implements AfterContentInit {
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
this.dataTable.loadingTemplate = this.template;
|
||||
}
|
||||
|
||||
}
|
@@ -15,10 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { NoContentTemplateComponent } from '../datatable/no-content-template.component';
|
||||
import { NoContentTemplateComponent } from './no-content-template.component';
|
||||
import { Injector } from '@angular/core';
|
||||
import { getTestBed, TestBed } from '@angular/core/testing';
|
||||
import { DataTableComponent } from './datatable.component';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
describe('NoContentTemplateComponent', () => {
|
||||
let injector: Injector;
|
@@ -15,13 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Directive,
|
||||
ContentChild,
|
||||
TemplateRef,
|
||||
AfterContentInit
|
||||
} from '@angular/core';
|
||||
import { DataTableComponent } from './datatable.component';
|
||||
import { Directive, ContentChild, TemplateRef, AfterContentInit } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
@Directive({
|
||||
selector: 'no-content-template'
|
||||
@@ -31,8 +26,7 @@ export class NoContentTemplateComponent implements AfterContentInit {
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(
|
||||
private dataTable: DataTableComponent) {
|
||||
constructor(private dataTable: DataTableComponent) {
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
3
ng2-components/ng2-alfresco-datatable/src/i18n/en.json
Normal file
3
ng2-components/ng2-alfresco-datatable/src/i18n/en.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
|
||||
}
|
Reference in New Issue
Block a user