Compare commits

...
79 Commits
Author SHA1 Message Date
Yasa-Nataliya 77960e37ad modified code 2023-07-28 04:32:08 +00:00
Yasa-Nataliya 3d6ac31eb0 modified the data-automation-id 2023-07-27 15:20:20 +00:00
Yasa-Nataliya f190795c48 added unit test cases for new functionality 2023-07-27 09:13:51 +00:00
Yasa-Nataliya b208f2e688 fix for unit test 2023-07-27 05:06:27 +00:00
Yasa-Nataliya 7e13faf645 fix for unit test cases 2023-07-26 17:08:47 +00:00
Yasa-Nataliya b4e541161d fix for unit test 2023-07-26 14:58:19 +00:00
Yasa-Nataliya 1119d7f135 empty commit 2023-07-26 14:37:00 +00:00
Yasa-Nataliya 75d7e98dff minor changes 2023-07-26 11:25:42 +00:00
Yasa-Nataliya 12e98b9371 modified changes 2023-07-26 10:51:27 +00:00
Yasa-Nataliya d9e3a903d1 added styles 2023-07-26 08:28:51 +00:00
Yasa-Nataliya 4dbed99fd8 changes for theme colors 2023-07-26 06:26:27 +00:00
Yasa-Nataliya 0a4b316c9b Implemented changes as per the requirement 2023-07-25 17:53:51 +00:00
Denys Vuika 80a6dadbfa enable flags for tags/categories in the metadata card (#8783) 2023-07-25 14:05:28 +01:00
MichalKinas f8f72d7f1a [ACS-5179] Add search facet tabbed component for creator and modifier (#8775) 2023-07-25 13:06:05 +01:00
Maurizio Cacace 8eb43b00ad HXOR-167: send slack message in case of release failures (#8781)
* HXOR-167: send slack message in case of release failures

* remove username
2023-07-25 10:37:54 +02:00
dependabot[bot] cb3f264265 Bump graphql-request from 6.0.0 to 6.1.0 (#8777)
Dependabot couldn't find the original pull request head commit, 8c2d9dd09bb1c8a41a67fff5f0e5d516e33ed9c1.

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 15:00:11 -04:00
dependabot[bot] 7676cb6a22 Bump material-icons from 1.13.8 to 1.13.9 (#8778)
Dependabot couldn't find the original pull request head commit, 66ae31c75cf131fd294368d27a1735a65afd2cda.

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-24 17:46:53 +02:00
Alfresco Buildandmauriziovitale 049fb16c6b [ci:force][auto-commit] Update dependencies JS:6.3.0-1054 (#8774)
Co-authored-by: mauriziovitale <mauriziovitale@users.noreply.github.com>
2023-07-24 09:28:11 +02:00
Denys Vuika e20de99974 [ACS-5687] info drawer layout fix for header (#8772) 2023-07-24 09:28:11 +02:00
swapnil.verma 640a736530 [ACS-4985] Resolved e2e test cases
[ACS-4985] Revert test fix for e2e execution. Updated search.config.ts for e2e test cases
Testing global install of webdriver-manager for e2e webdriver fix
[ACS-4985] Resolved e2e test failures
[ACS-4985] Increased value for drag emulation to account for increased width of the side filters panel in demo-shell search results window.
[ACS-4985] Resolved unit test failures
[ACS-4985] Resolved lint issues
[ACS-4985] Moved new components to v6.2.0 in versionIndex.md
[ACS-4985] Added documentation to versionIndex.md and README.md
[ACS-4985] Moved inLast input field back to input type number.
[ACS-4985] Resolved issue where typing a special character after adding some numbers in the 'In the last' input field would clear out the field
[ACS-4985] Updated test cases after query generation changes
[ACS-4985] Added missing null check when generating query
[ACS-4985] Added *ngFor back to the search-date-range-advanced-tabbed.component.html
[ACS-4985] Updated query generation logic. Now both 'In the last' and 'Between' options use the start date to end date query format
[ACS-4985] Removed ANY case from switch (will be handled by default case)
[ACS-4985] Split declarations into multiple lines
[ACS-4985] Fixed code smell in regex
[ACS-4985] Updated dates in documentation
[ACS-4985] Updated documentation
[ACS-4985] Added link for AngularMaterial bug for CSS workaround
[ACS-4985] Added test cases for end date validation. Fixed minor issue when setting invalid date error on between date form fields
[ACS-4985] Added validation when user manually enters the start and end dates
[ACS-4985] Added borders to inputs
[ACS-4985] Updated test cases for SearchDateRangeAdvancedTabbedComponent
[ACS-4985] Transferred business logic from SearchDateRangeAdvancedComponent and SearchFilterTabbedComponent to SearchDateRangeAdvancedTabbedComponent. Updated test cases accordingly
[ACS-4985] Resolved PR review comments
[ACS-4985] Removed unused code from base-query-builder.service.ts
[ACS-4985] Resolved linting and unit test issues
[ACS-4985] Resolved minor issues where switching between tabs could sometime cause the tab content to not show up
[ACS-4985] Resolved minor issues with display label creation
[ACS-4985] Updated component to use MatDateFnsAdapter. BetweenStartDate and BetweenEndDate are now formatted when selected from the calender
[ACS-4985] Resolved issue where clear button would not clear the values properly
[ACS-4985] Added @angular/material-date-fns-adapter package
[ACS-4985] Added image for updated documentation
[ACS-4985] Added validation to SearchDateRangeAdvancedComponent
[ACS-4985] Updated documentation for components
[ACS-4985] Removed disableUpdateOnSubmit flag from search widgets
[ACS-4985] Updated the documentation for the components
[ACS-4985] Added test cases for SearchDateRangeAdvancedTabbedComponent. Moved pending logic from template to typescript
[ACS-4985] Added clear and apply button to SearchDateRangeAdvancedTabbedComponent. Moved logic from template to typescript file
[ACS-4985] Updated test cases for SearchFilterTabbedComponent. Added safety checks to component
[ACS-4985] Added field validation to test case
[ACS-4985] Updated SearchDateRangeAdvancedTabbed component to no longer use getters and setters
[ACS-4985] Updated test cases for SearchDateRangeAdvancedComponent. Minor updates to the component template and logic. Component no longer uses getters and setters in template
[ACS-4985] Updated SearchDateRangeAdvancedTabbed component to use variables instead of getters and setters
[ACS-4985] Updated app.cconfig for demo-shell to use new date-range-advanced configuration
ACS-4985 Fixed issue with nx build, some clean ups, using changes in configuration
[ACS-4985] Updated test cases for changed date format
[ACS-4985] Updated date formats for SearchDateRangeAdvancedComponent
[ACS-4985] Removed fdescribe test cases for SearchDateRangeAdvancedComponent.
[ACS-4985] Fixed test cases for SearchDateRangeAdvancedComponent.
[ACS-4985] Fixed erroneous imports
[ACS-4985] Added license headers and re-ordered imports
[ACS-4985] Updated test cases for SearchDateRangeAdvancedComponent from moment.js to date-fns
[ACS-4985] Migrated SearchDateRangeAdvancedComponent from moment.js to date-fns
Added import for BaseQueryBuilderService in public-api.ts. Fixes #8647
[ACS-4985] Updated imports in test cases
[ACS-4985] Added exports for SearchDateRangeAdvanced and SearchFilterTabbed components to public-api.ts. Updated imports in both components
[ACS-4985] Resolved minor issue where the reset method would still trigger multiple api calls when used with the TabbedComponent
[ACS-4985] Added test cases for SearchDateRangeAdvancedComponent. Minor update to test cases for SearchFilterTabbedComponent
[ACS-4985] Updated Labels for 'In last' date range option
[ACS-4985] Updated SearchModule declarations. Fixed minor typo in SearchFilterTabbedComponent
[ACS-4985] Added test cases for SearchFilterTabbedComponent. Added test case placeholders for SearchDateRangeAdvancedComponent
[ACS-4985] Added data-automation-id to search-date-range-advanced.component.html
[ACS-4985] Added test cases for SearchFilterTabbedComponent
[ACS-4985] Removed vertical mode from SearchFilterTabbedComponent
[ACS-4985] Updated UI for search filters. Minor fixes
[ACS-4985] Added documentation for SearchFilterTabbedComponent and SearchDateRangeAdvancedComponent
[ACS-4985] Added compatibility of all search filters/facets with SearchFilterTabbedComponent
[ACS-4985] Using widget-composite component now correctly updates the search query on submit. Added optional property to disable update on submit button click for widget-composite.
[ACS-4985] Added SearchFilterTabbedComponent and SearchDateRangeAdvancedComponent. Added config for using the new components
2023-07-24 09:28:11 +02:00
SheenaMalhotra182 c8b4083f32 [ACS-5480] Bug Fix for multiple process/task filters (#8757)
* added a check before pushing filters

* moved the check inside a method and added unit tests for method

* renamed duplicate variables

* improved unit tests

* linting fixes

* linting fixes

* linting fixes

* removed unnecessary expects

* linting fix and added JS doc

* linting fixes - removed types from doc

* added unit tests for createDefaultFilter scenario

* linting fixes

* moved mock test data to mock data files
2023-07-21 14:38:11 +05:30
Alfresco Buildandmauriziovitale 2c937060d2 [ci:force][auto-commit] Update dependencies JS:6.3.0-1052 (#8748)
Co-authored-by: mauriziovitale <mauriziovitale@users.noreply.github.com>
2023-07-21 10:48:55 +02:00
Mykyta Maliarchuk 2a4507d529 [ACS-5266] Advanced Search - New component for Category facet (#8764)
* [ACS-5266] new component for category facet

* [ACS-5266] fixed tests & docs

* [ACS-5266] some fixes

* [ACS-5266] linting

* [ACS-5266] some improvements

* [ACS-5266] reduced observable from child component

* [ACS-5266] fixed docs

* [ACS-5266] rebase & improvements

* [ACS-5266] typo
2023-07-21 09:27:31 +02:00
Popovics András 1ebac21251 [HXCS-1479] Breadcrumbs as secondary entry point (#8750)
* Move breadcrumb outside of the core

* Fix styling

* Fix storybook
2023-07-20 16:13:09 +02:00
dependabot[bot] e0ab94c680 Bump word-wrap from 1.2.3 to 1.2.4 (#8767)
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 13:14:58 +02:00
Rafal Szmit 570b5d53c2 [AAE-15762] downgrade google chrome to 114 (#8770)
* downgrade google chrome to 114

* trigger ci

* apt allow downgrades
2023-07-20 13:09:47 +02:00
Denys Vuika 1a4d7ba008 [ACS-5629] enhanced way of providing translations (#8763)
* enhanced way providing translations

* update documentation

* update documentation

* test fixes

* try add missing module import

* inject i18n to core module to cause the setup
2023-07-18 20:06:09 +01:00
AleksanderSklorz d70f689e06 [ACS-5183] properties facet file size and file type (#8766)
* ACS-5183 Created component which displays form to search nodes by file type and size

* ACS-5183 Validate proper value in number input and allow to use custom file types

* ACS-5183 Corrected problem with styles, case insensitive compare for extensions

* ACS-5183 Added translations, styles for selecting type, proper comparator for types

* ACS-5183 Prevent adding custom file type when selecting existing one

* ACS-5183 Corrected bytes for each file size unit and clear number input when value is incorrect

* ACS-5183 Added documentation for search properties component, updated documentation for search chip autocomplete input and taking values from settings

* ACS-5183 Unit tests

* ACS-5183 Added automation ids

* ACS-5183 Added missing license header

* ACS-5183 Fixed lint issues

* ACS-5183 Fixed build issue
2023-07-18 15:45:00 +02:00
dependabot[bot] cffbdd51e4 Bump karma-chrome-launcher from 3.1.1 to 3.2.0 (#8760)
Bumps [karma-chrome-launcher](https://github.com/karma-runner/karma-chrome-launcher) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/karma-runner/karma-chrome-launcher/releases)
- [Changelog](https://github.com/karma-runner/karma-chrome-launcher/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma-chrome-launcher/compare/v3.1.1...v3.2.0)

---
updated-dependencies:
- dependency-name: karma-chrome-launcher
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-17 20:37:53 +01:00
Denys Vuika f45d69eb49 [ACS-5620] stabilise unit tests by switching to standard Angular api (#8759)
* switch to standard TestBed api for unit testing

* test fixes

* test fixes

* test fixes

* test fixes

* test fixes

* test fixes

* test fixes

* test fixes

* test fixes
2023-07-15 15:02:33 +01:00
Grzegorz Jaśkowski 574bff2d8d [ACS-5572] Add deprecated attribute to Like and Rating components (#8756) 2023-07-14 22:12:49 +01:00
Grzegorz Jaśkowski e37b03cbb4 ACS-5571 Add deprecated attribute to Webscript component (#8755) 2023-07-14 22:11:51 +01:00
dependabot[bot] e5d04abfab Bump semver from 5.7.1 to 5.7.2 in /lib/cli (#8753)
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-14 16:05:32 +02:00
dependabot[bot] a451654e5f Bump semver from 5.7.1 to 5.7.2 (#8754)
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-14 16:05:16 +02:00
Aayush Rohila 77210f43c3 [ACS-5145] Align header row with data rows. (#8732)
* [ACS-5145] Align header row with data rows.

* Styled email and status header for disabled to sort.

* update to accomodate change in another PR
2023-07-14 18:52:49 +05:30
dependabot[bot] 46616f038b Bump semver from 5.3.0 to 5.7.2 in /tools/tslint-rules (#8747)
Bumps [semver](https://github.com/npm/node-semver) from 5.3.0 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.3.0...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-13 12:26:27 +02:00
Tomasz Gnyp 484211d322 [AAE-15519] Fix - Assign To filter UI is broken (#8751) 2023-07-12 15:13:33 +02:00
7951eba089 GH Auto: Upstream dependencies JS-API:6.3.0-1031 (#8741)
* [ci:force][auto-commit] Update dependencies JS:6.3.0-1031

* Trigger CI

---------

Co-authored-by: mauriziovitale <mauriziovitale@users.noreply.github.com>
Co-authored-by: arditdomi <ardit.domi@hyland.com>
2023-07-10 18:08:07 +02:00
Ehsan Rezaei 6e203d3aa0 [AAE-15610] - Fixed column resizing issue (#8742)
* [AAE-15610] - Fixed column resizing issue

* AAE-15610: Code improvement

* AAE-15610: Added coverPadding input to resize directive

* AAE-15610: Code Improvement by setting first and last column width based on padding dynamically

* AAE-15610: Fixing lint issue
2023-07-10 10:39:22 +02:00
Alfresco BuildandMichalKinas 11155e3882 [ci:force][auto-commit] Update dependencies JS:6.3.0-1025 (#8740)
Co-authored-by: MichalKinas <MichalKinas@users.noreply.github.com>
2023-07-05 22:37:43 +02:00
Mykyta Maliarchuk fceb7ecb9e make resetNewFolderPagination method public again (#8739) 2023-07-05 16:32:45 +01:00
Maurizio Vitale b832beb387 people and group covered already (#8738) 2023-07-05 15:25:57 +01:00
Tomasz Gnyp 10afd501af Fix username pipe div text assign (#8737) 2023-07-05 13:36:33 +02:00
Ehsan Rezaei 8a0769a3c9 [AAE-15523] Setting default value for csrf check (#8736) 2023-07-04 19:57:23 +02:00
Mykyta Maliarchuk 54542c8b2b [ACS-5399] Fix incomplete multi-character sanitization (#8707)
* [ACS-5399] sanitization fix

* [ACS-5399] sanitization fix

* [ACS-5399] sanitization fix

* [ACS-5399] sanitization fix

* [ACS-5399] sanitization fix for comments.component

* [ACS-5399] sanitization fix for highlight-transform.service

* [ACS-5399] sanitization fix

* [ACS-5399] sanitization highlight-transform.service

* [ACS-5399] removed empty contructor

* [ACS-5399] linting

* [ACS-5399] fixed unit test

* [ACS-5399] linting

* [ACS-5399] fixed e2e

* [ACS-5399] added unit test to core

* [ACS-5399] added unit test to core

* [ACS-5399] test fix
2023-07-04 17:20:34 +01:00
dependabot[bot] dc06accace Bump @playwright/test from 1.33.0 to 1.35.1 (#8726)
Bumps [@playwright/test](https://github.com/Microsoft/playwright) from 1.33.0 to 1.35.1.
- [Release notes](https://github.com/Microsoft/playwright/releases)
- [Commits](https://github.com/Microsoft/playwright/compare/v1.33.0...v1.35.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-04 15:32:38 +01:00
Mykyta Maliarchuk 8fba7449e4 [ACS-5401] Fix unsafe HTML constructed from library input (#8725)
* [ACS-5401] sucurity fix

* [ACS-5401] fix tests

* [ACS-5401] security fix
2023-07-04 14:30:44 +01:00
dependabot[bot] addcc6fb34 Bump sass-loader from 13.2.2 to 13.3.2 (#8727)
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 13.2.2 to 13.3.2.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v13.2.2...v13.3.2)

---
updated-dependencies:
- dependency-name: sass-loader
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-04 14:30:06 +01:00
Denys Vuika 4452007471 Hide document list private api (#8735)
* hide private document list api

* hide private datatable api
2023-07-04 14:29:43 +01:00
Tomasz Gnyp 0ffbf9fbe2 [AAE-15522] Fix - Dropdown variable error messages are displayed at modeling part 2 (#8734)
* Revert preview flag changes

* add get preview state method to form cloud service
2023-07-04 14:39:02 +02:00
AleksanderSklorz b50b701da8 ACS-5406 Removed some importants (#8733) 2023-07-04 06:24:04 -04:00
Mykyta Maliarchuk 2f3f5ae02b [ACS-5314] Data table row should be clickable anywhere (#8671)
* [ACS-5314] bug fix

* [ACS-5314] empty commit

* rebase

* [ACS-5314] rebase

* [ACS-5314] fixed multiselect on checkbox

* [ACS-5314] fixed checkbox selector for e2e
2023-07-04 11:10:31 +02:00
Tomasz Gnyp a933070fc3 [AAE-15522] Fix - Dropdown variable error messages are displayed at modeling level (#8730) 2023-07-04 09:37:08 +02:00
Maurizio Vitale 3b3fd5ab9a run from Mon to Fri (#8729) 2023-07-03 11:40:51 +01:00
AleksanderSklorz c813bde005 ACS-5403 Prevent possibility to override prototype (#8719) 2023-06-30 18:20:38 +01:00
Maurizio Vitale ecbf571451 Revert "test e2e (#8723)" (#8724)
This reverts commit ad8259ece7.
2023-06-29 19:52:58 +01:00
Maurizio Vitale ad8259ece7 test e2e (#8723) 2023-06-29 16:47:46 +01:00
Maurizio Vitale 0fa61a2893 [AAE-15499] QA Failure provide more context on slack notification (#8720)
* sharing data with files

* sharing data with files

* disable check

* add shell

* skip step

* skip step

* fix tab

* run e2e

* failing e2e

* failing e2e make fail

* failing e2e make fail

* use js action

* fix template

* test action

* fix

* fix test

* fix test

* use action

* use action fix

* use action fix

* use action fix

* use action fix

* use action fix

* use action fix

* use action fix

* use action fix

* Normal run

* verify slack groups

* verify slack groups

* verify slack groups

* verify slack groups

* refactor

* remove useless code

* remove useless code

* use space as separator

* use space as separator

* use ga channel

* append only for cron

* run e2e job only if affected

* simulate process

* fix logic

* fix logic

* fix output

* almost done
2023-06-29 16:27:10 +01:00
Tomasz Gnyp e3ea23da37 [AAE-15082][AAE-15081] Resolve the options coming from a json variabl… (#8673)
* [AAE-15082][AAE-15081] Resolve the options coming from a json variable for a dropdown

* split method to smaller parts and remove duplications in units

* fix unit tests

* get variables from API call

* [AAE-15082] Add handle form variable

* replace variableId by variableName

* improve code
2023-06-29 17:21:14 +02:00
Maurizio Vitale dabe4ca279 Revert "improve jobs deps (#8717)" (#8722)
This reverts commit 9f8d93ea04.
2023-06-29 15:55:20 +01:00
dependabot[bot] 25073c0b37 Bump socket.io-parser from 4.2.2 to 4.2.4 (#8712)
Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 4.2.2 to 4.2.4.
- [Release notes](https://github.com/socketio/socket.io-parser/releases)
- [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-parser/compare/4.2.2...4.2.4)

---
updated-dependencies:
- dependency-name: socket.io-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 13:07:12 -04:00
Maurizio Vitale 23be41d676 revert use of action (#8718) 2023-06-28 16:09:24 +01:00
Maurizio Vitale 9f8d93ea04 improve jobs deps (#8717)
* improve jobs deps

* remove from old
2023-06-28 16:04:35 +01:00
Vito Albano ac3d959364 [AAE-15480] - fixed variables name and added mat card variable (#8713)
* [AAE-15480] - fixed variables name and added mat card variable

* [AAE-15480] - updated variable names
2023-06-28 15:49:01 +01:00
Maurizio Vitale 567e264d93 simulating a change without code (#8715) 2023-06-28 14:47:36 +01:00
mauriziovitale 4c3b29d5b5 fix lib path 2023-06-28 14:43:24 +01:00
Maurizio Vitale ee863391e1 [AAE-15422] Publish bundles only if libs are affected by merged code (#8694)
* Publish only if code is affected

* use ncc vercel

* ignore

* ignore

* ignore nodemodules

* remove test

* Update .gitignore only action dist
2023-06-28 14:34:32 +01:00
Rafal Szmit 1f74f5e1b1 [AAE-15269] update calendar locators (#8711)
* [AAE-15269] update calendar locators

* exclude C277288

* trigger ci [ci:force][link-adf:dev-rszmit-AAE-15269]
2023-06-28 13:24:14 +02:00
MichalKinas ee588df85b [ACS-5436] Logical search final version (#8709)
* [ACS-5436] Logical search final version

* [ACS-5436] CR fixes

* [ACS-5436] Remove unnecessary escape characters
2023-06-28 06:55:47 +02:00
Amedeo Leporeanderomano 7abebf0652 [AAE-12501] Align JS API (#8344)
* [AAE-12501] Provide an AlfrescoApiService implementation that disable the AlfrescoApi oauth initialization when we use new oidc implementation

* [AAE-12501] Replace oauth2Auth with authentication service, define get username as abstract

* [AAE-12501] Replace sitesService with authentication service since sitesService get the username from oauth2Auth

* [AAE-12501] Call implicitLogin by authentication service

* [AAE-12501] Replace Oauth2Auth with AlfrescoApi and call the custom api without using authentication

* [AAE-12501] Replace oauth2Auth with authentication service to get the token

* [AAE-12501] Replace oauth2Auth with alfrescoApi

* remove unneeded JS-API dep
move auth in the right place

* [AAE-10501] Rename alfresco-api.http-client to adf-http-client

* [AAE-10501] Remove config from a CoreModule, a different service is provided in AuthModule to use angular http client instead of super agent

* [AAE-10501] Disable AlfrescoApi oauth initialization while using new adf oidc authentication

* [AAE-12501] Replace alfresco api client with AdfHttpClient

* [AAE-12501] Restore get username methods

* [AAE-12501] Get username with authentication service

* [AAE-12501] removee unused method

* [AAE-12501] Trigger on login when token is received

* [AAE-12501] Fix content-services unit test

* [AAE-12501] Fix import

* [AAE-12501] Fix core unit tests

* [AAE-12501] Fix process-services-cloud unit tests

* [AAE-12501] Create a request options interface with the needed props, remove the import from js-api, return the body from request

* [AAE-12501] Fix process-services-cloud unit tests without Expectation

* [AAE-12501] Fix Core secondary entrypoints unit tests are not executed: move test.ts one level up in order to find all the spec files into the secondary entrypoints folders and update path

* [AAE-12501] Fix Core unit tests that weren't executed because of the previous test.ts wrong location

* [AAE-12501] Fix authentication token_issued subscription

* add emitters

* [AAE-12501] Replace Math.random() to fix hospot security issue, fix lint issues

* [AAE-12501] Install event-emitter dependency

* [AAE-12501] Comment temporary setCsrfToken because is not possible to import app config service from core due to circular dependencies

* [AAE-12501] Get disableCsrf from app config serviice when app configuration is loaded

* [AAE-12501] Fix license-header lint issue

* [AAE-14221] Regenerate lock file

* [AAE-14221] Fix sonarcloud issues

* [AAE-12501] Remove wrong character

* [AAE-12501] Regenerate lock file

* [AAE-12501] Fix BC: update alfresco api response error

---------

Co-authored-by: eromano <eugenioromano16@gmail.com>
2023-06-27 17:22:30 +02:00
Popovics András 037dce0ae7 [HXCS-1479] Core breadcrumbs component (#8695)
* Moving breadcrumb component from Hyland UI to ADF and renaming selectors and entities with proper prefix

* Cleaning up a bit the breadcumbs

* Stabilising breadcrumbs and adding storibook

* Fix change requests
2023-06-27 15:09:37 +02:00
AleksanderSklorz bce1f34c2f [ACS-5398] Fixed useless regular expression character (#8710) 2023-06-27 13:56:13 +02:00
Diogo Bastos 3f4fe2a898 [AAE-15252] Update ADF interfaces to reflect update from BE (#8672)
* [AAE-15252] Update ADF ApplicationInstanceModel and Descriptor interfaces and AppsProcessCloudService service

* [AAE-15252] Update app.config.json file
2023-06-27 10:45:52 +01:00
Ardit Domi f0d2456f42 [AAE-15018] - Add support for roles as part of the access token authorization (#8642) 2023-06-27 09:57:40 +01:00
Mykyta Maliarchuk b16777cce0 [ACS-5364] bug fix (#8686) 2023-06-27 04:39:28 -04:00
AleksanderSklorz 9dd9347d17 [ACS-5397] Corrected checking whitespace characters in regexp (#8704) 2023-06-27 08:33:26 +02:00
AleksanderSklorz be896b502f [ACS-5395] Fixed possibility to containing script by string (#8696)
* ACS-5395 Fixed possibility to containing script by string

* ACS-5395 Fixed possibility to containing script by string
2023-06-27 08:10:27 +02:00
AleksanderSklorz 1078e27cba [ACS-5199] upgrade 3rd party depedencies to support angular 14 and later (#8669)
* ACS-5199 Upgraded ng2-charts and chart.js

* ACS-5199 Removed reports tab from demoshell

* ACS-5199 Versions correction after upgrading charts

* ACS-5199 Replaced ngx-monaco-editor with ngx-monaco-editor-v2
2023-06-27 08:09:59 +02:00
Ehsan Rezaei 82540a4496 [AAE-15259] Making Identity User Info Component customizable (#8675)
* [AAE-15259] Making Identity User Info Component customizable

* AAE-15259: Added margin right var
2023-06-27 02:04:39 +01:00
602 changed files with 20002 additions and 16655 deletions
@@ -0,0 +1,90 @@
name: Append content to Artifact
description: 'Allow the user to append content to an existing artifact'
inputs:
artifact-name:
description: 'The name of the artifact'
required: true
type: string
file-name:
description: 'The name of the file with extension created in the artifact'
required: true
type: string
content:
description: 'The content to append'
type: string
default: ""
runs:
using: "composite"
steps:
- run: echo "Artifact Append"
shell: bash
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: ${{ inputs.artifact-name }}
- run: ls
shell: bash
- name: Append content
uses: actions/github-script@v6
env:
contentFile: ${{ inputs.content }}
fileName: ${{ inputs.file-name }}
with:
script: |
const fs = require('fs');
const affectedLib = process.env.contentFile;
const fileName = process.env.fileName;
core.info(`Input Filename: ${fileName}`);
core.info(`Input content: ${affectedLib}`);
const content = read(fileName)
core.info(`File content: ${content}`);
appendContent(content, affectedLib);
function read(filename) {
try {
const contentFile = fs.readFileSync(filename, 'utf8').replace('\n','');
return contentFile;
} catch (err) {
core.error(err);
}
}
function write(filename, content) {
try {
fs.writeFileSync(filename, content);
} catch (err) {
core.error(err);
}
}
function appendContent(content, append) {
let changedContent;
const libs = content.split(' ');
if (libs?.length>0) {
if (libs.length === 1 && libs[0] === '') {
libs[0] = append;
changedContent = libs[0];
}
else if (!libs.includes(append)) {
libs.push(append);
changedContent = libs.join(' ');
} else {
core.info(`Lib ${append} already affected`);
}
}
if (changedContent != undefined){
core.info(`File content append: ${changedContent}`)
write(fileName, changedContent);
}
}
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: ${{ inputs.artifact-name }}
path: ${{ inputs.file-name }}
@@ -0,0 +1,40 @@
name: Extract Artifact
description: 'Allow the user to extract content from an artifact'
inputs:
artifact-name:
description: 'The name of the artifact'
required: true
type: string
file-name:
description: 'The name of the file with extension created in the artifact'
required: true
type: string
content:
description: 'The init content the file should have'
type: string
default: ""
outputs:
result:
description: "the value extrated from the file inside the artifact"
value: ${{ steps.extract.outputs.result }}
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
- run: echo "Artifact Extract"
shell: bash
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: ${{ inputs.artifact-name }}
- id: extract
shell: bash
run: |
value=`cat ${{ inputs.file-name }}`
echo "print $value"
echo "result=$value" >> $GITHUB_OUTPUT
@@ -0,0 +1,32 @@
name: Initialize Artifact
description: 'Allow the user to initialize an empty artifact used globally'
inputs:
artifact-name:
description: 'The name of the artifact'
required: true
type: string
file-name:
description: 'The name of the file with extension created in the artifact'
required: true
type: string
content:
description: 'The init content the file should have'
type: string
default: ""
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
- name: Create empty artifact
shell: bash
run:
echo "${{inputs.content}}" > ${{ inputs.file-name }}
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: ${{ inputs.artifact-name }}
path: ${{ inputs.file-name }}
+44 -24
View File
@@ -46,6 +46,21 @@ inputs:
runs:
using: "composite"
steps:
- name: Determine if affected
shell: bash
id: determine-affected
run: |
isAffected=false
affectedLibs=$(npx nx print-affected --type=lib --select=projects ${NX_CALCULATION_FLAGS} --plain)
if [[ $affectedLibs =~ "${{ inputs.e2e-test-id }}" ]]; then
isAffected=true
fi;
echo "Determine if ${{ inputs.e2e-test-id }} is affected: $isAffected";
echo "isAffected=$isAffected" >> $GITHUB_OUTPUT
- name: print value
shell: bash
run: |
echo "value: ${{ steps.determine-affected.outputs.isAffected }}"
- name: use APA as PROXY host if apa-proxy is set
shell: bash
run: |
@@ -76,8 +91,9 @@ runs:
- name: check EXTERNAL-CS is UP
shell: bash
if: ${{ inputs.check-external-cs-env == 'true' }}
if: ${{ inputs.check-external-cs-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }}
run: |
echo "running: check EXTERNAL-CS is UP"
set -u;
./node_modules/@alfresco/adf-cli/bin/adf-cli \
check-cs-env \
@@ -87,8 +103,9 @@ runs:
- name: Check CS is UP
shell: bash
if: ${{ inputs.check-cs-env == 'true' }}
if: ${{ inputs.check-cs-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }}
run: |
echo "Running: Check CS is UP"
set -u;
./node_modules/@alfresco/adf-cli/bin/adf-cli \
check-cs-env \
@@ -98,8 +115,9 @@ runs:
- name: check PS is UP
shell: bash
if: ${{ inputs.check-ps-env == 'true' }}
if: ${{ inputs.check-ps-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }}
run: |
echo "Running: check PS is UP"
set -u;
./node_modules/@alfresco/adf-cli/bin/adf-cli init-aps-env \
--host "$E2E_HOST" \
@@ -109,8 +127,9 @@ runs:
- name: check PS-CLOUD is UP
shell: bash
if: ${{ inputs.check-ps-cloud-env == 'true' }}
if: ${{ inputs.check-ps-cloud-env == 'true' && steps.determine-affected.outputs.isAffected == 'true' }}
run: |
echo "running: check PS-CLOUD is UP"
set -u;
./node_modules/@alfresco/adf-cli/bin/adf-cli init-aae-env \
--oauth "$E2E_IDENTITY_HOST_APA" \
@@ -134,36 +153,37 @@ runs:
echo $PROXY_HOST_BPM
echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV
- name: run test with retries
id: retry_run
- name: run test
id: e2e_run
if: ${{ steps.determine-affected.outputs.isAffected == 'true' }}
env:
FOLDER: "${{ inputs.e2e-test-folder }}"
PROVIDER: "${{ inputs.e2e-test-provider }}"
AUTH_TYPE: "${{ inputs.e2e-test-auth }}"
E2E_TEST_ID: "${{ inputs.e2e-test-id }}"
DEPS: "${{ inputs.deps }}"
uses: nick-fields/retry@v2.8.2
shell: bash
run: |
set -u;
if [[ ${{ inputs.e2e-test-folder }} == 'content-services/upload' ]]; then
export DISPLAY=:99
chromedriver --url-base=/wd/hub &
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional
bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" "browser" || exit 1
else
bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" || exit 1
fi
- name: Trace failing e2e
if: ${{ steps.determine-affected.outputs.isAffected == 'true' && github.event_name == 'schedule' && failure() }}
uses: ./.github/actions/artifact-append
with:
timeout_minutes: 40
max_attempts: 2
retry_wait_seconds: 30
shell: bash
command: |
set -u;
export GH_ACTION_RETRY_COUNT=$(cat ${GITHUB_OUTPUT} | grep -E '^[0-9]{1,2}$' | tail -n1)
echo "RETRY GH_ACTION_RETRY_COUNT = <$GH_ACTION_RETRY_COUNT>"
if [[ ${{ inputs.e2e-test-folder }} == 'content-services/upload' ]]; then
export DISPLAY=:99
chromedriver --url-base=/wd/hub &
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional
bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" "browser" || exit 1
else
bash ./scripts/github/e2e/e2e.sh "$E2E_TEST_ID" "$DEPS" || exit 1
fi
artifact-name: global-e2e-result
file-name: e2e-failures.txt
content: "${{ inputs.e2e-test-id }}"
- name: upload artifacts on gh
id: upload_gh
if: ${{ steps.determine-affected.outputs.isAffected == 'true' }}
uses: actions/upload-artifact@v3
with:
name: e2e-artifact-output
@@ -0,0 +1,21 @@
name: "print affected libs"
description: "Retrive the affected libs based on the based and head input"
inputs:
base:
description: 'the base sha'
required: true
type: string
default: main
head:
description: 'the head sha'
required: true
type: string
default: HEAD
output:
affected:
description: 'the affected libs of the repo'
affected_is_empty:
description: 'true or false accondingly'
runs:
using: "node16"
main: 'dist/index.js'
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+476
View File
@@ -0,0 +1,476 @@
{
"name": "print-affected-libs",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "print-affected-libs",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1"
}
},
"node_modules/@actions/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"node_modules/@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"dependencies": {
"@actions/io": "^1.0.1"
}
},
"node_modules/@actions/github": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
"dependencies": {
"@actions/http-client": "^2.0.1",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
}
},
"node_modules/@actions/http-client": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
"dependencies": {
"tunnel": "^0.0.6"
}
},
"node_modules/@actions/io": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"dependencies": {
"@octokit/types": "^6.40.0"
},
"peerDependencies": {
"@octokit/core": ">=2"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"dependencies": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
},
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"node_modules/@octokit/types": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"dependencies": {
"@octokit/openapi-types": "^12.11.0"
}
},
"node_modules/@vercel/ncc": {
"version": "0.36.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz",
"integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==",
"dev": true,
"bin": {
"ncc": "dist/ncc/cli.js"
}
},
"node_modules/before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/node-fetch": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
},
"dependencies": {
"@actions/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"requires": {
"@actions/http-client": "^2.0.1",
"uuid": "^8.3.2"
}
},
"@actions/exec": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"requires": {
"@actions/io": "^1.0.1"
}
},
"@actions/github": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
"requires": {
"@actions/http-client": "^2.0.1",
"@octokit/core": "^3.6.0",
"@octokit/plugin-paginate-rest": "^2.17.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
}
},
"@actions/http-client": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
"integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
"requires": {
"tunnel": "^0.0.6"
}
},
"@actions/io": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="
},
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.3",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "12.11.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.21.3",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
"requires": {
"@octokit/types": "^6.40.0"
}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
"requires": {
"@octokit/types": "^6.39.0",
"deprecation": "^2.3.1"
}
},
"@octokit/request": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/types": {
"version": "6.41.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
"requires": {
"@octokit/openapi-types": "^12.11.0"
}
},
"@vercel/ncc": {
"version": "0.36.1",
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.36.1.tgz",
"integrity": "sha512-S4cL7Taa9yb5qbv+6wLgiKVZ03Qfkc4jGRuiUQMQ8HGBD5pcNRnHeYM33zBvJE4/zJGjJJ8GScB+WmTsn9mORw==",
"dev": true
},
"before-after-hook": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"node-fetch": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"requires": {
"wrappy": "1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
}
}
@@ -0,0 +1,20 @@
{
"name": "print-affected-libs",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"build": "ncc build src/index.js -o dist --source-map"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^5.1.1"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1"
}
}
@@ -0,0 +1,32 @@
const core = require('@actions/core');
const exec = require('@actions/exec');
async function run() {
const base = core.getInput('base', {required: false }) || '5288597580';
core.setOutput('affected_is_empty', 'true');
let affected = '';
let myError = '';
const options = {};
options.listeners = {
stdout: (data) => {
affected += data.toString()
},
stderr: (data) => {
myError += data.toString();
}
};
await exec.exec(`npx nx print-affected --target=build --select=tasks.target.project --base=${base} --head=${head}`, [], options)
const affectedTrimmed = affected.trim();
if (affectedTrimmed !== '') {
core.setOutput('affected_is_empty', 'false');
}
core.notice(`Retriving affected libs: ${affectedTrimmed}`);
core.setOutput('affected', affectedTrimmed);
}
run();
+2 -2
View File
@@ -7,7 +7,7 @@ runs:
- name: Install google chrome
shell: bash
run: |
wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
wget -q https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.133-1_amd64.deb
sudo apt install -y --allow-downgrades ./google-chrome-stable_114.0.5735.133-1_amd64.deb
sudo ln -s /usr/bin/google-chrome /usr/bin/chrome
chrome --version
@@ -0,0 +1,49 @@
name: Identify the slack group
description: 'Identify the slack group area based on the affected'
inputs:
affected:
description: 'The name of the affected lib'
required: true
type: string
outputs:
groups:
description: "the slack groups"
value: ${{ steps.group.outputs.result }}
runs:
using: "composite"
steps:
- name: Append group
id: group
uses: actions/github-script@v6
env:
affectedLib: ${{ inputs.affected }}
with:
script: |
const affectedLib = process.env.affectedLib;
core.info(`Input ${affectedLib}`);
const slackGroups = new Set();
const AlfrescoQAGroup = '@alfresco-testing-qa';
const HxpQAGroup = '@hxp-studio-qa-group';
const libs = affectedLib.split(' ')
if (libs.includes('content-services') || libs.includes('process-services')) {
slackGroups.add(AlfrescoQAGroup);
}
if (libs.includes('process-services-cloud')) {
slackGroups.add(HxpQAGroup);
}
if (libs.includes('core')) {
slackGroups.add(AlfrescoQAGroup);
slackGroups.add(HxpQAGroup);
}
const result = Array.from(slackGroups.values()).join(' ');
core.info(`Result ${result}`);
return result;
+12 -1
View File
@@ -1,8 +1,9 @@
name: "cron e2e daily"
on:
workflow_dispatch:
schedule:
- cron: '0 12 * * *'
- cron: '0 12 * * 1-5' #At 12:00 on every day-of-week from Monday through Friday.
env:
BASE_REF: ${{ github.base_ref }}
@@ -68,6 +69,16 @@ env:
PROXY_HOST_ECM: ${{ secrets.E2E_HOST }}
jobs:
init-artifact:
runs-on: ubuntu-latest
name: Initialize artifacts
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/artifact-initialize
with:
artifact-name: global-e2e-result
file-name: e2e-failures.txt
run-e2e:
name: run e2e
uses: ./.github/workflows/pull-request.yml
+15 -1
View File
@@ -488,6 +488,20 @@ jobs:
name: Final Results
needs: [check-if-pr-is-approved, check-package-lock, setup, unit-tests, lint, build-libs, e2e, e2e-storybook]
steps:
- uses: actions/checkout@v3
- name: Log e2e result
id: e2e-result
if: ${{ github.event_name == 'schedule' }}
uses: ./.github/actions/artifact-extract
with:
artifact-name: global-e2e-result
file-name: e2e-failures.txt
- name: identify-slack-group
id: groups
if: ${{ github.event_name == 'schedule' }}
uses: ./.github/actions/slack-group-area
with:
affected: ${{ steps.e2e-result.outputs.result }}
- uses: slackapi/slack-github-action@v1.23.0
name: Nofify QA failure
if: ${{ github.event_name == 'schedule' && contains(needs.*.result, 'failure') }}
@@ -495,7 +509,7 @@ jobs:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
with:
channel-id: 'C016SMNNL8L' #guild-channel
slack-message: "🔴 Warning: The daily ADF cronjob failed\nWorkflow run : <https://github.com/Alfresco/alfresco-ng2-components/actions/runs/${{ github.run_id }}| here>\n"
slack-message: "🔴 Warning: The daily ADF cronjob failed\nWorkflow run : <https://github.com/Alfresco/alfresco-ng2-components/actions/runs/${{ github.run_id }}| here>\nDetails: ${{ steps.e2e-result.outputs.result }}\nArea: ${{ steps.groups.outputs.groups}}"
- name: workflow failure
run: exit 1
if: ${{ contains(needs.*.result, 'failure') }}
+16
View File
@@ -222,3 +222,19 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- uses: ./.github/actions/npm-check-bundle
finalize:
if: always()
runs-on: ubuntu-latest
name: Final Results
needs: [release-demoshell, release-storybook, release-npm, npm-check-bundle]
steps:
- uses: slackapi/slack-github-action@v1.23.0
name: Nofify FE hxp-front-end-apps workflow failed
if: ${{ contains(toJson(needs.*.result), 'failure') }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
with:
channel-id: 'C04N93XU491' #hxp-front-end-apps
slack-message: "🔴 Warning: The release workflow of alfresco-ng2-components pipe failed\n Author: name:${{ github.event.pusher.name }}\n Workflow run : <https://github.com/Alfresco/alfresco-ng2-components/actions/runs/${{ github.run_id }}| here>\n>"
+2 -1
View File
@@ -7,7 +7,8 @@ workspace.xml
*.iml
.env.*
.env
dist/
dist
!./.github/actions/**/dist
e2e/.env.cloud
tmp
temp
+6 -4
View File
@@ -108,7 +108,7 @@
},
{
"glob": "**/*",
"input": "node_modules/ngx-monaco-editor/assets/monaco",
"input": "node_modules/monaco-editor",
"output": "/assets/monaco/"
}
],
@@ -303,7 +303,7 @@
"core": {
"projectType": "library",
"root": "lib/core",
"sourceRoot": "lib/core/src",
"sourceRoot": "lib/core",
"prefix": "adf",
"architect": {
"build": {
@@ -327,7 +327,7 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "lib/core/src/test.ts",
"main": "lib/core/test.ts",
"tsConfig": "lib/core/tsconfig.spec.json",
"karmaConfig": "lib/core/karma.conf.js",
"sourceMap": true,
@@ -348,7 +348,9 @@
"lib/core/auth/**/*.ts",
"lib/core/auth/**/*.html",
"lib/core/shell/**/*.ts",
"lib/core/shell/**/*.html"
"lib/core/shell/**/*.html",
"lib/core/breadcrumbs/**/*.ts",
"lib/core/breadcrumbs/**/*.html"
]
}
},
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "استخدم نموذج مخصص للرأس 'المستخدم'",
"CUSTOM_COLUMN_HEADER": "قالب رأس المستخدم المخصص"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "لم يتم تحديد تقرير. اختر تقريرًا من القائمة"
},
"PS-TAB": {
"TASKS-TAB": "المهام",
"PROCESSES-TAB": "العملية",
"REPORTS-TAB": "تقارير",
"SETTINGS-TAB": "إعدادات",
"START-TASK": "بدء مهمة",
"START-PROCESS": "بدء العملية",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "افتراضي",
"OPEN_DIALOG": "فتح الحوار",
"SHOW_LIST_LABEL": "انقر لعرض القائمة"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Použít vlastní šablonu pro záhlaví ,Uživatel",
"CUSTOM_COLUMN_HEADER": "Vlastní šablona záhlaví Uživatel"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Nebyly zvoleny žádné zprávy. Vyberte zprávu ze seznamu"
},
"PS-TAB": {
"TASKS-TAB": "Úkoly",
"PROCESSES-TAB": "Proces",
"REPORTS-TAB": "Protokoly",
"SETTINGS-TAB": "Nastavení",
"START-TASK": "Zahájit úkol",
"START-PROCESS": "Zahájit proces",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Výchozí",
"OPEN_DIALOG": "Otevřít dialogové okno",
"SHOW_LIST_LABEL": "Na seznam pro zobrazení klikněte"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Brug tilpasset skabelon til overskrift 'Bruger'",
"CUSTOM_COLUMN_HEADER": "Tilpasset brugeroverskriftskabelon"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Du skal vælge en rapport på listen til venstre"
},
"PS-TAB": {
"TASKS-TAB": "Opgaver",
"PROCESSES-TAB": "Proces",
"REPORTS-TAB": "Rapporter",
"SETTINGS-TAB": "Indstillinger",
"START-TASK": "Start opgave",
"START-PROCESS": "Start proces",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Standard",
"OPEN_DIALOG": "Åbn dialog",
"SHOW_LIST_LABEL": "Klik for at vise listen"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Benutzerdefinierte Vorlage für 'Benutzer'-Kopfzeile verwenden",
"CUSTOM_COLUMN_HEADER": "Benutzerdefinierte Vorlage für Benutzer-Kopfzeile"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Kein Bericht ausgewählt. Wählen Sie einen Bericht aus der Liste"
},
"PS-TAB": {
"TASKS-TAB": "Aufgaben",
"PROCESSES-TAB": "Prozess",
"REPORTS-TAB": "Berichte",
"SETTINGS-TAB": "Einstellungen",
"START-TASK": "Aufgabe starten",
"START-PROCESS": "Prozess starten",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Standard",
"OPEN_DIALOG": "Dialog öffnen",
"SHOW_LIST_LABEL": "Klicken Sie, um die Liste anzuzeigen"
}
}
-4
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Use custom template for 'User' header",
"CUSTOM_COLUMN_HEADER": "Custom User Header Template"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "No report selected. Choose a report from the list"
},
"PS-TAB": {
"TASKS-TAB": "Tasks",
"PROCESSES-TAB": "Process",
"REPORTS-TAB": "Reports",
"SETTINGS-TAB": "Settings",
"START-TASK": "Start task",
"START-PROCESS": "Start process",
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Utilizar una plantilla personalizada para el encabezado 'Usuario'",
"CUSTOM_COLUMN_HEADER": "Plantilla de encabezado de usuario personalizado"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "No se ha seleccionado ningún informe. Elija un informe de la lista."
},
"PS-TAB": {
"TASKS-TAB": "Tareas",
"PROCESSES-TAB": "Proceso",
"REPORTS-TAB": "Informes",
"SETTINGS-TAB": "Configuración",
"START-TASK": "Iniciar tarea",
"START-PROCESS": "Iniciar proceso",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Predeterminado",
"OPEN_DIALOG": "Abrir cuadro de diálogo",
"SHOW_LIST_LABEL": "Hacer clic para mostrar la lista"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Käytä mukautettua mallia \"Käyttäjä\"-otsikolle",
"CUSTOM_COLUMN_HEADER": "Mukautettu käyttäjäotsikon malli"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Yhtään raporttia ei ole valittuna. Valitse raportti luettelosta."
},
"PS-TAB": {
"TASKS-TAB": "Tehtävät",
"PROCESSES-TAB": "Prosessi",
"REPORTS-TAB": "Raportit",
"SETTINGS-TAB": "Asetukset",
"START-TASK": "Aloita tehtävä",
"START-PROCESS": "Käynnistä prosessi",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Oletus",
"OPEN_DIALOG": "Avaa valintaikkuna",
"SHOW_LIST_LABEL": "Näytä luettelo napsauttamalla"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Utiliser un modèle personnalisé pour l'en-tête 'Utilisateur'",
"CUSTOM_COLUMN_HEADER": "Modèle d'en-tête Utilisateur personnalisé"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Aucun rapport sélectionné. Choisissez un rapport dans la liste"
},
"PS-TAB": {
"TASKS-TAB": "Tâches",
"PROCESSES-TAB": "Processus",
"REPORTS-TAB": "Rapports",
"SETTINGS-TAB": "Paramètres",
"START-TASK": "Démarrer la tâche",
"START-PROCESS": "Démarrer le processus",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Par défaut",
"OPEN_DIALOG": "Boîte de dialogue Ouvrir",
"SHOW_LIST_LABEL": "Cliquer pour afficher la liste"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Usa il modello personalizzato per l'intestazione \"Utente\"",
"CUSTOM_COLUMN_HEADER": "Modello personalizzato per intestazione Utente"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Nessun rapporto selezionato. Scegliere un rapporto dall'elenco"
},
"PS-TAB": {
"TASKS-TAB": "Compiti",
"PROCESSES-TAB": "Processo",
"REPORTS-TAB": "Rapporti",
"SETTINGS-TAB": "Impostazioni",
"START-TASK": "Avvia compito",
"START-PROCESS": "Avvia processo",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Predefinito",
"OPEN_DIALOG": "Apri finestra di dialogo",
"SHOW_LIST_LABEL": "Fai clic per mostrare l'elenco"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "「ユーザー」ヘッダーにカスタムテンプレートを使用",
"CUSTOM_COLUMN_HEADER": "カスタムユーザーヘッダーテンプレート"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "レポートが選択されていません。リストからレポートを選択してください。"
},
"PS-TAB": {
"TASKS-TAB": "タスク",
"PROCESSES-TAB": "プロセス",
"REPORTS-TAB": "レポート",
"SETTINGS-TAB": "設定",
"START-TASK": "タスクの開始",
"START-PROCESS": "プロセスの開始",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "デフォルト",
"OPEN_DIALOG": "ダイアログを開く",
"SHOW_LIST_LABEL": "クリックしてリストを表示"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Bruk egendefinert mal for toppteksten 'bruker'",
"CUSTOM_COLUMN_HEADER": "Egendefinert topptekst for bruker"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Ingen rapport valgt. Velg en rapport fra listen"
},
"PS-TAB": {
"TASKS-TAB": "Oppgaver",
"PROCESSES-TAB": "Prosess",
"REPORTS-TAB": "Rapporter",
"SETTINGS-TAB": "Innstillinger",
"START-TASK": "Start oppgave",
"START-PROCESS": "Start prosess",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Standard",
"OPEN_DIALOG": "Åpne dialog",
"SHOW_LIST_LABEL": "Klikk for å vise listen"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Aangepaste sjabloon voor 'User'-koptekst gebruiken",
"CUSTOM_COLUMN_HEADER": "Aangepaste sjabloon voor User-koptekst"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Geen rapport geselecteerd. Kies een rapport uit de lijst"
},
"PS-TAB": {
"TASKS-TAB": "Taken",
"PROCESSES-TAB": "Proces",
"REPORTS-TAB": "Rapporten",
"SETTINGS-TAB": "Instellingen",
"START-TASK": "Taak starten",
"START-PROCESS": "Proces starten",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Standaard",
"OPEN_DIALOG": "Dialoogvenster Openen",
"SHOW_LIST_LABEL": "Klik om de lijst weer te geven"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Użyj szablonu niestandardowego dla nagłówka 'Użytkownik'",
"CUSTOM_COLUMN_HEADER": "Szablon niestandardowy nagłówka Użytkownik"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Nie wybrano raportu. Wybierz raport z listy."
},
"PS-TAB": {
"TASKS-TAB": "Zadania",
"PROCESSES-TAB": "Proces",
"REPORTS-TAB": "Raporty",
"SETTINGS-TAB": "Ustawienia",
"START-TASK": "Rozpocznij zadanie",
"START-PROCESS": "Rozpocznij proces",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Domyślne",
"OPEN_DIALOG": "Otwórz okno dialogowe",
"SHOW_LIST_LABEL": "Kliknij, aby wyświetlić listę"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Usar modelo personalizado para o cabeçalho 'Usuário'",
"CUSTOM_COLUMN_HEADER": "Modelo personalizado do cabeçalho Usuário"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Nenhum relatório selecionado. Escolha um relatório na lista"
},
"PS-TAB": {
"TASKS-TAB": "Tarefas",
"PROCESSES-TAB": "Processo",
"REPORTS-TAB": "Relatórios",
"SETTINGS-TAB": "Configurações",
"START-TASK": "Iniciar tarefa",
"START-PROCESS": "Iniciar processo",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Padrão",
"OPEN_DIALOG": "Abrir caixa de diálogo",
"SHOW_LIST_LABEL": "Clique para mostrar a lista"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Использовать пользовательский шаблон для заголовка «Пользователь»",
"CUSTOM_COLUMN_HEADER": "Пользовательский шаблон заголовка пользователя"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Отчет не выбран. Выберите отчет из списка"
},
"PS-TAB": {
"TASKS-TAB": "Задачи",
"PROCESSES-TAB": "Процесс",
"REPORTS-TAB": "Отчеты",
"SETTINGS-TAB": "Параметры",
"START-TASK": "Начать задачу",
"START-PROCESS": "Начать процесс",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "По умолчанию",
"OPEN_DIALOG": "Открыть диалог",
"SHOW_LIST_LABEL": "Нажмите для отображения списка"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "Använd anpassad mall för \"Användare\"-rubrik",
"CUSTOM_COLUMN_HEADER": "Anpassad användarhuvudmall"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "Ingen rapport vald. Välj en rapport från listan"
},
"PS-TAB": {
"TASKS-TAB": "Uppgifter",
"PROCESSES-TAB": "Process",
"REPORTS-TAB": "Rapporter",
"SETTINGS-TAB": "Inställningar",
"START-TASK": "Starta uppgift",
"START-PROCESS": "Starta process",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "Standard",
"OPEN_DIALOG": "Öppna dialogruta",
"SHOW_LIST_LABEL": "Klicka för att visa listan"
}
}
+1 -5
View File
@@ -224,13 +224,9 @@
"USE_CUSTOM_COLUMN_HEADER": "为“用户”标题使用自定义模板",
"CUSTOM_COLUMN_HEADER": "自定义用户标题模板"
},
"ANALYTICS_REPORT": {
"NO_REPORT_MESSAGE": "未选择报告,请从列表中选择报告"
},
"PS-TAB": {
"TASKS-TAB": "任务",
"PROCESSES-TAB": "流程",
"REPORTS-TAB": "报告",
"SETTINGS-TAB": "设置",
"START-TASK": "启动任务",
"START-PROCESS": "启动流程",
@@ -389,4 +385,4 @@
"DEFAULT_SEARCH": "默认值",
"OPEN_DIALOG": "打开对话框",
"SHOW_LIST_LABEL": "单击以显示列表"
}
}
+23 -3
View File
@@ -322,6 +322,23 @@
}
}
},
{
"id": "createdModifiedDateRange",
"name": "Date",
"enabled": true,
"component": {
"selector": "date-range-advanced",
"settings": {
"dateFormat": "dd-MMM-yy",
"maxDate": "today",
"field": "cm:created, cm:modified",
"displayedLabelsByField": {
"cm:created": "Created Date",
"cm:modified": "Modified Date"
}
}
}
},
{
"id": "queryType",
"name": "Type",
@@ -1433,13 +1450,16 @@
],
"alfresco-deployed-apps": [
{
"name": "candidatebaseapp"
"name": "candidatebaseapp",
"displayName": "candidatebaseapp"
},
{
"name": "simpleapp"
"name": "simpleapp",
"displayName": "simpleapp"
},
{
"name": "subprocessapp"
"name": "subprocessapp",
"displayName": "subprocessapp"
}
],
"aspect-visible": {
+7 -21
View File
@@ -18,17 +18,17 @@
import { BrowserModule } from '@angular/platform-browser';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ChartsModule } from 'ng2-charts';
import { NgChartsModule } from 'ng2-charts';
import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule } from '@ngx-translate/core';
import {
AppConfigService,
TRANSLATION_PROVIDER,
DebugAppConfigService,
CoreModule,
CoreAutomationService,
AuthModule
AuthModule,
provideTranslations
} from '@alfresco/adf-core';
import { ExtensionsModule } from '@alfresco/adf-extensions';
import { AppComponent } from './app.component';
@@ -59,7 +59,7 @@ import { TaskAttachmentsComponent } from './components/process-service/task-atta
import { ProcessAttachmentsComponent } from './components/process-service/process-attachments.component';
import { SharedLinkViewComponent } from './components/shared-link-view/shared-link-view.component';
import { DemoPermissionComponent } from './components/permissions/demo-permissions.component';
import { MonacoEditorModule } from 'ngx-monaco-editor';
import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
import { ContentModule } from '@alfresco/adf-content-services';
import { InsightsModule } from '@alfresco/adf-insights';
import { ProcessModule } from '@alfresco/adf-process-services';
@@ -151,7 +151,7 @@ registerLocaleData(localeSv);
ProcessServicesCloudModule.forRoot(),
ExtensionsModule.forRoot(),
ThemePickerModule,
ChartsModule,
NgChartsModule,
AppCloudSharedModule,
MonacoEditorModule.forRoot()
],
@@ -211,22 +211,8 @@ registerLocaleData(localeSv);
],
providers: [
{ provide: AppConfigService, useClass: DebugAppConfigService }, // not use this service in production
{
provide: TRANSLATION_PROVIDER,
multi: true,
useValue: {
name: 'app',
source: 'resources'
}
},
{
provide: TRANSLATION_PROVIDER,
multi: true,
useValue: {
name: 'lazy-loading',
source: 'resources/lazy-loading'
}
},
provideTranslations('app', 'resources'),
provideTranslations('lazy-loading', 'resources/lazy-loading'),
AppNotificationsService,
{
provide: APP_INITIALIZER,
@@ -20,7 +20,7 @@ import { ConfigEditorComponent } from './config-editor.component';
import { Routes, RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { CoreModule } from '@alfresco/adf-core';
import { MonacoEditorModule } from 'ngx-monaco-editor';
import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
const routes: Routes = [
{
@@ -27,7 +27,6 @@ import { ObjectDataTableAdapter, AuthenticationService } from '@alfresco/adf-cor
<li>Global i18n: {{ 'APP_LAYOUT.DATATABLE_LAZY' | translate }}</li>
<li>Local i18n (work in progress): {{ 'LAZY.TEXT' | translate }}</li>
<li>isLoggedIn: {{ isLoggedIn }}</li>
<li>ECM username: {{ username }}
</ul>
`
})
@@ -39,10 +38,6 @@ export class LazyLoadingComponent {
return this.auth.isLoggedIn();
}
get username(): string {
return this.auth.getEcmUsername();
}
constructor(private auth: AuthenticationService) {
this.data = new ObjectDataTableAdapter(
// data
@@ -245,29 +245,6 @@
</div>
</div>
</mat-tab>
<mat-tab id="report-header" href="#report"
label="{{'PS-TAB.REPORTS-TAB' | translate}}">
<div class="app-grid">
<div class="app-grid-item app-reports-menu">
<span><h5>Report List</h5></span>
<mat-divider></mat-divider>
</div>
<div class="app-grid-item app-reports-details">
<adf-analytics
*ngIf="report"
[appId]="appId"
[reportId]="report.id"
[hideParameters]="false"
(editReport)="onEditReport()"
(reportSaved)="onReportSaved($event)"
(reportDeleted)="onReportDeleted()">
</adf-analytics>
<div *ngIf="!report">
<span>{{'ANALYTICS_REPORT.NO_REPORT_MESSAGE' | translate}}</span>
</div>
</div>
</div>
</mat-tab>
<mat-tab id="settings-header" href="#settings"
label="{{'PS-TAB.SETTINGS-TAB' | translate}}">
<div class="app-grid">
@@ -104,13 +104,13 @@
min-width: 225px;
}
.app-reports-menu, .app-settings-menu {
.app-settings-menu {
flex: 1 1 300px;
max-width: 300px;
min-width: 300px;
}
.app-tasks-details, .app-tasks-start, .app-processes-details, .app-processes-start, .app-reports-details, .app-settings-details {
.app-tasks-details, .app-tasks-start, .app-processes-details, .app-processes-start, .app-settings-details {
flex: 1 1 auto;
min-width: auto;
}
@@ -38,9 +38,6 @@ import {
FORM_FIELD_VALIDATORS, FormRenderingService, FormService, AppConfigService, PaginationComponent, UserPreferenceValues,
AlfrescoApiService, UserPreferencesService, LogService, DataCellEvent, NotificationService
} from '@alfresco/adf-core';
import { AnalyticsReportListComponent } from '@alfresco/adf-insights';
import {
ProcessFiltersComponent,
ProcessInstance,
@@ -109,9 +106,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
@ViewChild('activitiStartProcess')
activitiStartProcess: StartProcessInstanceComponent;
@ViewChild('analyticsReportList', { static: true })
analyticsReportList: AnalyticsReportListComponent;
@Input()
appId: number = null;
@@ -120,7 +114,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
@Output()
changePageSize = new EventEmitter<Pagination>();
selectFirstReport = false;
multiSelectTask = false;
multiSelectProcess = false;
selectionMode = 'single';
@@ -147,7 +140,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
activeTab: number = this.tabs.tasks; // tasks|processes|reports
taskFilter: FilterRepresentationModel;
report: any;
processFilter: UserProcessInstanceFilterRepresentation;
blobFile: any;
flag = true;
@@ -313,10 +305,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.changePageSize.emit(event);
}
onReportClick(event: any): void {
this.report = event;
}
onSuccessTaskFilterList(): void {
this.applyTaskFilter(this.activitiFilter.getCurrentFilter());
}
@@ -380,19 +368,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.currentProcessInstanceId = processInstanceId;
}
onEditReport(): void {
this.analyticsReportList.reload();
}
onReportSaved(reportId: number): void {
this.analyticsReportList.reload(reportId);
}
onReportDeleted(): void {
this.analyticsReportList.reload();
this.analyticsReportList.selectReport(null);
}
navigateStartProcess(): void {
this.currentProcessInstanceId = currentProcessIdNew;
}
@@ -3,7 +3,6 @@
margin-left: 5px;
.app-search-settings {
width: 260px;
border: 1px solid #eee;
}
@@ -17,6 +17,9 @@
import { Component, ViewEncapsulation } from '@angular/core';
/**
* @deprecated This component uses Like and Rating components that are not used in ACA/ADW/ACC and can be removed.
*/
@Component({
selector: 'app-social',
templateUrl: './social.component.html',
@@ -29,6 +29,9 @@ const routes: Routes = [
}
];
/**
* @deprecated This module uses Like and Rating components that are not used in ACA/ADW/ACC and can be removed.
*/
@NgModule({
imports: [
CommonModule,
@@ -18,6 +18,9 @@
import { Component } from '@angular/core';
import { LogService } from '@alfresco/adf-core';
/**
* @deprecated Webscript component has never been turned into a product and has no UI/UX and no use cases in ACA/ADW/ACC.
*/
@Component({
selector: 'app-webscript',
templateUrl: './webscript.component.html'
@@ -29,6 +29,9 @@ const routes: Routes = [
}
];
/**
* @deprecated Webscript component has never been turned into a product and has no UI/UX and no use cases in ACA/ADW/ACC.
*/
@NgModule({
imports: [
CommonModule,
@@ -56,8 +56,7 @@ export class AppNotificationsService {
) {
this.alfrescoApiService.alfrescoApiInitialized.subscribe(() => {
if (this.isProcessServicesEnabled() && this.notificationsEnabled) {
this.alfrescoApiService.getInstance().oauth2Auth.once('token_issued', () => {
this.authenticationService.once('token_received').subscribe(() => {
const deployedApps = this.appConfigService.get('alfresco-deployed-apps', []);
if (deployedApps?.length) {
deployedApps.forEach((app) => {
@@ -69,11 +68,8 @@ export class AppNotificationsService {
});
});
}
});
}
});
}
+4
View File
@@ -289,14 +289,18 @@ for more information about installing and using the source code.
| [Search Chip Input Component](content-services/components/search-chip-input.component.md) | Displays input for providing phrases display as "chips". | [Source](../lib/content-services/src/lib/search/components/search-chip-input/search-chip-input.component.ts) |
| [Search Chip Autocomplete Input component](content-services/components/search-chip-autocomplete-input.component.md) | Displays an input with autocomplete options. | [Source](../lib/content-services/src/lib/search/components/search-chip-autocomplete-input/search-chip-autocomplete-input.component.ts) |
| [Search Chip List Component](content-services/components/search-chip-list.component.md) | Displays search criteria as a set of "chips". | [Source](../lib/content-services/src/lib/search/components/search-chip-list/search-chip-list.component.ts) |
| [Search Date Range Advanced Component](content-services/components/search-date-range-advanced.component.md) | Displays a UI to configure different kinds of search criteria around date. Options are 'Anyytime', 'In the last' and 'Between' | [Source](../lib/content-services/src/lib/search/components/search-date-range-advanced-tabbed/search-date-range-advanced/search-date-range-advanced.component.ts) |
| [Search control component](content-services/components/search-control.component.md) | Displays a input text that shows find-as-you-type suggestions. | [Source](../lib/content-services/src/lib/search/components/search-control.component.ts) |
| [Search date range component](content-services/components/search-date-range.component.md) | Implements a search widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-date-range/search-date-range.component.ts) |
| [Search date range advanced tabbed component](content-services/components/search-date-range-advanced-tabbed.component.md) | Implements a tabbed advanced search widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-date-range-advanced-tabbed/search-date-range-advanced-tabbed.component.ts) |
| [Search datetime range component](content-services/components/search-datetime-range.component.md) | Implements a search widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-datetime-range/search-datetime-range.component.ts) |
| [Search Filter Autocomplete Chips component](content-services/components/search-filter-autocomplete-chips.component.md) | Implements a search widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-filter-autocomplete-chips/search-filter-autocomplete-chips.component.ts) |
| [Search Filter Chips component](content-services/components/search-filter-chips.component.md) | Represents a chip based container component for custom search and faceted search settings. | [Source](../lib/content-services/src/lib/search/components/search-filter-chips/search-filter-chips.component.ts) |
| [Search Filter component](content-services/components/search-filter.component.md) | Represents a main container component for custom search and faceted search settings. | [Source](../lib/content-services/src/lib/search/components/search-filter/search-filter.component.ts) |
| [Search Filter Tabbed component](content-services/components/search-filter-tabbed.component.md) | Represents a container component for creating tabbed layout. | [Source](../lib/content-services/src/lib/search/components/search-filter/search-filter.component.ts) |
| [Search Form component](content-services/components/search-form.component.md) | Search Form screenshot | [Source](../lib/content-services/src/lib/search/components/search-form/search-form.component.ts) |
| [Search Logical Filter component](content-services/components/search-logical-filter.component.md) | Displays 3 chip inputs each representing different logical condition for search query. | [Source](../lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts) |
| [Search Properties component](content-services/components/search-properties.component.md) | Allows to search by file size and type.| [Source](../lib/content-services/src/lib/search/components/search-properties/search-properties.component.ts) |
| [Search number range component](content-services/components/search-number-range.component.md) | Implements a number range widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-number-range/search-number-range.component.ts) |
| [Search radio component](content-services/components/search-radio.component.md) | Implements a radio button list widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-radio/search-radio.component.ts) |
| [Search slider component](content-services/components/search-slider.component.md) | Implements a numeric slider widget for the Search Filter component. | [Source](../lib/content-services/src/lib/search/components/search-slider/search-slider.component.ts) |
@@ -15,26 +15,32 @@ Represents an input with autocomplete options.
```html
<adf-search-chip-autocomplete-input
[autocompleteOptions]="allOptions"
[autocompleteOptions]="autocompleteOptions"
[onReset$]="onResetObservable$"
[allowOnlyPredefinedValues]="allowOnlyPredefinedValues"
(inputChanged)="onInputChange($event)"
(optionsChanged)="onOptionsChange($event)">
</adf-search-chip-autocomplete-input>
```
### Properties
| Name | Type | Default value | Description |
|---------------------------|--------------------------|----|-----------------------------------------------------------------------------------------------|
| autocompleteOptions | `string[]` | [] | Options for autocomplete |
| onReset$ | [`Observable`](https://rxjs.dev/guide/observable)`<void>` | | Observable that will listen to any reset event causing component to clear the chips and input |
| allowOnlyPredefinedValues | boolean | true | A flag that indicates whether it is possible to add a value not from the predefined ones |
| Name | Type | Default value | Description |
|---------------------------|--------------------------|----|-----------------------------------------------------------------------------------------------------------------------------------------------|
| autocompleteOptions | `AutocompleteOption[]` | [] | Options for autocomplete |
| onReset$ | [`Observable`](https://rxjs.dev/guide/observable)`<void>` | | Observable that will listen to any reset event causing component to clear the chips and input |
| allowOnlyPredefinedValues | boolean | true | A flag that indicates whether it is possible to add a value not from the predefined ones |
| placeholder | string | 'SEARCH.FILTER.ACTIONS.ADD_OPTION' | Placeholder which should be displayed in input. |
| compareOption | (option1: AutocompleteOption, option2: AutocompleteOption) => boolean | | Function which is used to selected options with all options so it allows to detect which options are already selected. |
| formatChipValue | (option: string) => string | | Function which is used to format custom typed options. |
| filter | (options: AutocompleteOption[], value: string) => AutocompleteOption[] | | Function which is used to filter out possible options from hint. By default it checks if option includes typed value and is case insensitive. |
### Events
| Name | Type | Description |
| ---- | ---- |-----------------------------------------------|
| optionsChanged | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string[]>` | Emitted when the selected options are changed |
| inputChanged | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string>` | Emitted when the input changes |
| optionsChanged | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<AutocompleteOption[]>` | Emitted when the selected options are changed |
## See also
@@ -1,49 +0,0 @@
---
Title: Search Chip Input component
Added: v6.1.0
Status: Active
Last reviewed: 2023-06-01
---
# [Search Chip Input component](../../../lib/content-services/src/lib/search/components/search-chip-input/search-chip-input.component.ts "Defined in search-chip-input.component.ts")
Represents an input with stacked list of chips as phrases added through input.
![Search Chip Input](../../docassets/images/search-chip-input.png)
## Basic usage
```html
<adf-search-chip-input
[label]="'Some label'"
[onReset]="onResetObservable"
(phrasesChanged)="handlePhraseChanged($event)">
</adf-search-chip-input>
```
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| label | `string` | | Label that will be associated with the input |
| addOnBlur | `boolean` | true | Specifies whether new phrase will be added when input blurs |
| onReset | [`Observable`](https://rxjs.dev/guide/observable)`<void>` | | Observable that will listen to any reset event causing component to clear the chips and input |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| phrasesChanged | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string[]>` | Emitted when new phrase is entered |
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search Logical Filter component](search-logical-filter.component.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search number range component](search-number-range.component.md)
- [Search radio component](search-radio.component.md)
- [Search slider component](search-slider.component.md)
- [Search text component](search-text.component.md)
@@ -0,0 +1,113 @@
---
Title: Search date range advanced tabbed component
Added: v6.2.0
Status: Active
Last reviewed: 2023-07-10
---
# [Search date range advanced tabbed component](../../../lib/content-services/src/lib/search/components/search-date-range-advanced-tabbed/search-date-range-advanced-tabbed.component.ts "Defined in search-date-range-advanced-tabbed.component.ts")
Represents a tabbed advanced date range [search widget](../../../lib/content-services/src/lib/search/models/search-widget.interface.ts) for
the [Search Filter component](search-filter.component.md).
![Date Range Advanced Widget](../../docassets/images/search-date-range-advanced-tabbed.png)
## Basic usage
```json
{
"search": {
"categories": [
{
"id": "createdModifiedDateRange",
"name": "Date",
"enabled": true,
"component": {
"selector": "date-range-advanced",
"settings": {
"dateFormat": "dd-MMM-yy",
"maxDate": "today",
"field": "cm:created, cm:modified",
"displayedLabelsByField": {
"cm:created": "Created Date",
"cm:modified": "Modified Date"
}
}
}
}
]
}
}
```
### Settings
| Name | Type | Description |
|------------------------|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| field | string | Fields to apply the query to. Multiple, comma separated fields can be passed, to create multiple tabs per field. Required value |
| dateFormat | string | Date format. Dates used by the datepicker are Javascript Date objects, using [date-fns](https://date-fns.org/v2.30.0/docs/format) for formatting, so you can use any date format supported by the library. Default is 'dd-MMM-yy (sample date - 07-Jun-23) |
| maxDate | string | A fixed date (in format mentioned above, default format: dd-MMM-yy) or the string `"today"` that will set the maximum searchable date. Default is today. |
| displayedLabelsByField | { [key: string]: string } | A javascript object containing the different display labels to be used for each tab name, identified by the field for a particular tab. |
## Details
This component creates a tabbed layout where each tab consists of the [SearchDateRangeAdvanced](./search-date-range-advanced-tabbed.component.md) component, which allows user to create a query containing multiple date related queries in one go.
See the [Search filter component](search-filter.component.md) for full details of how to use widgets in a search query.
### Custom date format
You can set the date range picker to work with any date format your app requires. You can use
any date format supported by the [date-fns](https://date-fns.org/v2.30.0/docs/format) library
in the `dateFormat` and in the `maxDate` setting:
```json
{
"search": {
"categories": [
{
"id": "createdModifiedDateRange",
"name": "Date",
"enabled": true,
"component": {
"selector": "date-range-advanced",
"settings": {
"dateFormat": "dd-MMM-yy",
"maxDate": "02-May-23",
"field": "cm:created, cm:modified",
"displayedLabelsByField": {
"cm:created": "Created Date",
"cm:modified": "Modified Date"
}
}
}
}
]
}
}
```
The [SearchDateRangeAdvanced](./search-date-range-advanced-tabbed.component.md) component allows 3 different kinds of date related operations to be performed.
Based on what information is provided to that component, this component will create different kinds of queries -
- Anytime - No date filters are applied on the `field`. This option is selected by default
- In the last - Allows to user to apply a filter to only show results from the last 'n' unit of time.
- Between - Allows the user to select a range of dates to filter the search results.
The queries generated by this filter when using the 'In the last' or 'Between' options is of the form -
`<field>:[<from_date> TO <to_date>]`
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search number range component](search-number-range.component.md)
- [Search radio component](search-radio.component.md)
- [Search slider component](search-slider.component.md)
- [Search text component](search-text.component.md)
- [Search filter tabbed component](search-filter-tabbed.component.md)
@@ -0,0 +1,47 @@
---
Title: Search date range advanced component
Added: v6.2.0
Status: Active
Last reviewed: 2023-07-10
---
# [Search date range advanced component](../../../lib/content-services/src/lib/search/components/search-date-range-advanced-tabbed/search-date-range-advanced/search-date-range-advanced.component.ts "Defined in search-date-range-advanced.component.ts")
Represents an advanced date range component for
the [SearchAdvancedDateRangeTabbedComponent](search-date-range-advanced-tabbed.component.md).
![Date Range Advanced Widget](../../docassets/images/search-date-range-advanced.png)
## Basic usage
```html
<adf-search-date-range-advanced></adf-search-date-range-advanced>
```
## Class Members
### Properties
| Name | Type | Description |
|--------------|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| field | string | Field to apply the query to. Required value |
| maxDate | string | A fixed date (default format: dd-MMM-yy) or the string `"today"` that will set the maximum searchable date. Default is today. |
| dateFormat | string | Date format. Dates used by the datepicker are Javascript Date objects, using [date-fns](https://date-fns.org/v2.30.0/docs/format) for formatting, so you can use any date format supported by the library. Default is 'dd-MMM-yy (sample date - 07-Jun-23) |
| initialValue | SearchDateRangeAdvanced | Initial value for the component |
### Events
| Name | Type | Description |
|---------------------|------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|
| changed | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<Partial<SearchDateRangeAdvanced>>` | Emitted whenever a change is made in the component values. Emits the changes being made in the component. |
| valid | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<boolean>` | Emitted whenever a change is made in the component values. Emits a flag indicating whether the current state of the component is valid or not. |
## Details
This component lets the user choose a variety of options to perform date related operations.
- Anytime - No date related data will be returned. This option is selected by default
- In the last - Allows user to perform date related operations over a period of time. The user can select the length of the period from current time,
as well as its unit. Currently, 3 units are supported - Days, Weeks, and Months.
- Between - Allows the user to select a range of dates to perform operations on.
@@ -0,0 +1,49 @@
---
Title: Search facet chip tabbed component
Added: v6.2.0
Status: Active
Last reviewed: 2023-07-18
---
# [Search facet chip tabbed component](../../../lib/content-services/src/lib/search/components/search-filter-chips/search-facet-chip-tabbed/search-facet-chip-tabbed.component.ts "Defined in search-facet-chip-tabbed.component.ts")
Implements a [facet widget](../../../lib/content-services/src/lib/search/models/facet-widget.interface.ts) consisting of creator and modifier facets inside tabbed component.
![Search facet chip tabbed](../../docassets/images/search-facet-chip-tabbed.png)
## Basic usage
When both creator and modifier facets are present in config file as stated below they will be merged into this component.
```json
{
"search": {
"facetFields": {
"fields": [
{
"mincount": 1,
"field": "creator",
"label": "SEARCH.FACET_FIELDS.CREATOR",
},
{
"mincount": 1,
"field": "modifier",
"label": "SEARCH.FACET_FIELDS.MODIFIER",
}
]
}
}
}
```
### Settings
| Name | Type | Description |
| ---- | ---- | ----------- |
| tabbedFacet | [TabbedFacetField](../../../lib/content-services/src/lib/search/models/tabbed-facet-field.interface.ts) | Tabbed facet configuration containing label, fields and facets to display. Required value |
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search chip autocomplete input component](search-chip-autocomplete-input.component.md)
@@ -28,7 +28,7 @@ Implements a [search widget](../../../lib/content-services/src/lib/search/models
"hideDefaultAction": true,
"allowOnlyPredefinedValues": false,
"field": "SITE",
"options": [ "Option 1", "Option 2" ]
"autocompleteOptions": [ {"value": "Option 1"}, {"value": "Option 2"} ]
}
}
}
@@ -42,7 +42,7 @@ Implements a [search widget](../../../lib/content-services/src/lib/search/models
| Name | Type | Description |
| ---- |----------|--------------------------------------------------------------------------------------------------------------------|
| field | `string` | Field to apply the query to. Required value |
| options | `string[]` | Predefined options for autocomplete |
| autocompleteOptions | `AutocompleteOption[]` | Predefined options for autocomplete |
| allowOnlyPredefinedValues | `boolean` | Specifies whether the input values should only be from predefined |
| allowUpdateOnChange | `boolean` | Enable/Disable the update fire event when text has been changed. By default is true |
| hideDefaultAction | `boolean` | Show/hide the widget actions. By default is false |
@@ -0,0 +1,41 @@
---
Title: Search filter tabbed component
Added: v6.2.0
Status: Active
Last reviewed: 2023-07-10
---
# [Search filter tabbed component](../../../lib/content-services/src/lib/search/components/search-filter-tabbed/search-filter-tabbed.component.ts "Defined in search-filter-tabbed.component.ts")
Represents a container for [Search Filters](search-filter.component.md) to provide a tabbed user interface for the filters.
![Search Filter Tabbed Widget](../../docassets/images/search-filter-tabbed.png)
## Basic Usage
```html
<adf-search-filter-tabbed>
<ng-container *ngFor="let field of fields">
<my-search-filter *adf-search-filter-tab="MyTabLabel"></my-search-filter>
</ng-container>
</adf-search-filter-tabbed>
```
In order to generate a tabbed widget for multiple search filters, you can pass in the search filter widget component as a content child of the adf-search-filter-tabbed component as shown above.
Additionally, you also have to make sure that the search filter being passed as a content child of the adf-search-filter-tabbed component, also has the adf-search-filter-tabbed directive applied on it,
with the name input property being assigned the value of whatever name should be displayed for that particular tab
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search date range advanced component](search-date-range-advanced.component.md)
- [Search number range component](search-number-range.component.md)
- [Search radio component](search-radio.component.md)
- [Search slider component](search-slider.component.md)
- [Search text component](search-text.component.md)
@@ -37,7 +37,9 @@ to build and execute the query.
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search date range advanced component](search-date-range-advanced.component.md)
- [Search number range component](search-number-range.component.md)
- [Search radio component](search-radio.component.md)
- [Search slider component](search-slider.component.md)
- [Search text component](search-text.component.md)
- [Search filter tabbed component](search-filter-tabbed.component.md)
@@ -7,7 +7,7 @@ Last reviewed: 2023-06-01
# [Search Logical Filter component](../../../lib/content-services/src/lib/search/components/search-logical-filter/search-logical-filter.component.ts "Defined in search-logical-filter.component.ts")
Implements a [search widget](../../../lib/content-services/src/lib/search/models/search-widget.interface.ts) consisting of 3 chip inputs representing logical conditions to form search query from.
Implements a [search widget](../../../lib/content-services/src/lib/search/models/search-widget.interface.ts) consisting of 4 inputs representing logical conditions to form search query from.
![Search Logical Filter](../../docassets/images/search-logical-filter.png)
@@ -45,14 +45,12 @@ Implements a [search widget](../../../lib/content-services/src/lib/search/models
## Details
This component lets the user provide logical conditions to apply to each `field` in the search query.
See the [Search chip input component](search-chip-input.component.md) for full details of how to use chip inputs.
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search Chip Input component](search-chip-input.component.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search number range component](search-number-range.component.md)
@@ -0,0 +1,61 @@
---
Title: Search Properties component
Added: v6.2.0
Status: Active
Last reviewed: 2023-07-13
---
# [Search Properties component](../../../lib/content-services/src/lib/search/components/search-properties/search-properties.component.ts "Defined in search-properties.component.ts")
Allows to search by file size and type.
![Search Properties](../../docassets/images/search-properties.png)
## Basic usage
```json
{
"id": "properties",
"name": "Properties",
"enabled": true,
"component": {
"selector": "properties",
"settings": {
"field": "content.size,cm:name",
"fileExtensions": [
"3g2", "3gp", "acp", "aep", "ai", "aiff", "apk", "arw", "avi", "bin", "bmp", "cgm", "class", "cr2",
"css", "csv", "dita", "dng", "doc", "docm", "docx", "dotm","dwg", "dwt", "eps", "flac", "flv", "fm",
"fodg", "gif", "gtar", "gz", "htm", "html", "icns", "ics", "ief", "indd", "jar", "java", "jp2", "jpeg",
"jpg", "js", "json", "jsp", "m4v", "man", "md", "mov", "mp3", "mp4", "mpeg", "mpp", "mrw", "msg", "nef",
"numbers", "odb", "odf", "odg", "odi", "odm", "odp", "ods", "odt", "oga", "ogg", "ogv", "ogx", "orf",
"ott", "pages", "pbm", "pdf", "pef", "pgm", "pmd", "png", "pnm", "pot", "potx", "ppam", "ppj", "pps",
"ppsm", "ppt", "pptm", "pptx", "ps", "psd", "rad", "raf", "rar", "rgb", "rss", "rtf", "rw2", "rwl",
"sda", "sdc", "sdd", "sdp", "sds", "sdw", "sgi", "sgl", "sgml", "sh", "sldm", "smf", "stw", "svg",
"swf", "sxi", "tar", "tex", "texi", "tif", "tiff", "ts", "tsv", "txt", "vsd", "vsdm", "vsdx", "vssm",
"vstm", "vstx", "wav", "webm", "wma", "wmv", "wpd", "wrl", "x3f", "xdp", "xhtml", "xla", "xlam", "xls",
"xlsb", "xlsm", "xlsx", "xltm", "xml", "xpm", "xwd", "z", "zip"
]
}
}
}
```
### Settings
| Name | Type | Description |
|----------------|----------|-------------------------------------------------------------------------------------------|
| field | string | Field/fields to apply the query to. First field for size, second for name. Required value |
| fileExtensions | string[] | List of preconfigured hints for extensions. |
## See also
- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
- [Search Query Builder service](../services/search-query-builder.service.md)
- [Search Widget Interface](../interfaces/search-widget.interface.md)
- [Search check list component](search-check-list.component.md)
- [Search date range component](search-date-range.component.md)
- [Search number range component](search-number-range.component.md)
- [Search radio component](search-radio.component.md)
- [Search slider component](search-slider.component.md)
- [Search text component](search-text.component.md)
@@ -14,7 +14,7 @@ Checks if the provided value is contained in the provided array.
<!-- {% raw %} -->
```HTML
<mat-option [disabled]="value | adfIsIncluded: arrayOfValues"</mat-option>
<mat-option [disabled]="value | adfIsIncluded: arrayOfValues : comparator"></mat-option>
```
<!-- {% endraw %} -->
+47 -55
View File
@@ -62,7 +62,7 @@ this.trans.get(
total: "122"
}
).subscribe(translation => {
this.translatedText = translation;
this.translatedText = translation;
});
```
@@ -79,16 +79,21 @@ general format of the path to this folder will be:
If you wanted English and French translations then you would add
`en.json` and `fr.json` files into the `i18n` folder and add your new keys:
// en.json
**en.json**
...
"WELCOME_MESSAGE": "Welcome!"
...
```json
{
"WELCOME_MESSAGE": "Welcome!"
}
```
// fr.json
...
"WELCOME_MESSAGE": "Bienvenue !"
...
**fr.json**
```json
{
"WELCOME_MESSAGE": "Bienvenue !"
}
```
The files follow the same hierarchical key:value JSON format as the built-in translations.
You can add new keys to your local files or redefine existing keys but the built-in definitions
@@ -97,66 +102,53 @@ look like the following:
```json
{
"title": "my app",
"LOGIN": {
"LABEL": {
"LOGIN": "Custom Sign In"
}
}
"title": "my app",
"LOGIN": {
"LABEL": {
"LOGIN": "Custom Sign In"
}
}
}
```
To enable the new translations in your app, you also need to register them in your
`app.module.ts` file. Import `TRANSLATION_PROVIDER` and add the path of your
translations folder to the `providers`:
To enable the new translations in your app, you also need to register them in your `app.module.ts` file using `provideTranslations` api:
```ts
// Other imports...
import { TRANSLATION_PROVIDER } from "@alfresco/adf-core";
...
import { provideTranslations } from "@alfresco/adf-core";
@NgModule({
imports: [
...
],
declarations: [
...
],
providers: [
{
provide: TRANSLATION_PROVIDER,
multi: true,
useValue: {
name: 'my-translations',
source: 'assets/my-translations'
}
}
...
providers: [
provideTranslations('my-translations', 'assets/my-translations')
]
})
export class MyModule {}
```
You can now use your new keys in your component:
```ts
...
ngOnInit() {
this.trans.use("fr");
this.trans.get("WELCOME_MESSAGE").subscribe(translation => {
this.translatedText = translation;
});
}
...
export class MyComponent implements OnInit {
translateService = inject(TranslationService);
translatedText = '';
ngOnInit() {
this.translateService.use("fr");
this.translatedText = this.translateService.instant('WELCOME_MESSAGE');
}
}
```
Note: the `source` property points to the web application root. Ensure you have
webpack correctly set up to copy all the i18n files at compile time.
Note: the `source` property points to the web application root.
Do not forget to configure your Angular application to copy the newly created files to the build output, for example:
```text
index.html
assets/ng2-alfresco-core/i18n/en.json
...
**angular.json**
```json
{
"glob": "**/*",
"input": "lib/core/src/lib/i18n",
"output": "/assets/adf-core/i18n"
}
```
You can register as many entries as you like.
@@ -180,4 +172,4 @@ class MyComponent {
## See Also
- [Internationalization](../../user-guide/internationalization.md)
- [Internationalization](../../user-guide/internationalization.md)
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

+13
View File
@@ -12,6 +12,7 @@ backend services have been tested with each released version of ADF.
## Versions
- [v6.2.0](#v620)
- [v6.1.0](#v610)
- [v6.0.0](#v600)
- [v5.1.0](#v510)
@@ -42,6 +43,18 @@ backend services have been tested with each released version of ADF.
- [v2.1.0](#v210)
- [v2.0.0](#v200)
## v6.2.0
<!--v620 start-->
- [Search Properties component](content-services/components/search-properties.component.md)
- [Search Date Range Advanced Component](content-services/components/search-date-range-advanced.component.md)
- [Search Date Range Advanced Tabbed Component](content-services/components/search-date-range-advanced-tabbed.component.md)
- [Search Filter Tabbed Component](content-services/components/search-filter-tabbed.component.md)
- [Search Facet Chip Tabbed Component](content-services/components/search-facet-chip-tabbed.md)
<!--v620 end-->
## v6.1.0
<!--v610 start-->
@@ -150,7 +150,8 @@ describe('Comment', () => {
await expect(await commentsPage.getTime(0)).toMatch(/(ago|few)/);
});
it('[C280022] Should not be able to add an HTML or other code input into the comment input filed', async () => {
it('[C280022] Should treat HTML code as a regular string', async () => {
const resultStr = comments.codeType.replace(/\s\s+/g, ' ');
await viewerPage.viewFile(pngFileModel.name);
await viewerPage.clickInfoButton();
await viewerPage.checkInfoSideBarIsDisplayed();
@@ -160,7 +161,7 @@ describe('Comment', () => {
await commentsPage.checkUserIconIsDisplayed();
await commentsPage.getTotalNumberOfComments('Comments (1)');
await expect(await commentsPage.getMessage(0)).toEqual('First name: Last name:');
await expect(await commentsPage.getMessage(0)).toEqual(resultStr);
await expect(await commentsPage.getUserName(0)).toEqual(userFullName);
await expect(await commentsPage.getTime(0)).toMatch(/(ago|few)/);
});
@@ -1,248 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { createApiService,
GroupCloudComponentPage,
GroupIdentityService,
IdentityService,
LoginPage,
PeopleCloudComponentPage,
RolesService
} from '@alfresco/adf-testing';
import { browser } from 'protractor';
import { PeopleGroupCloudComponentPage } from './../pages/people-group-cloud-component.page';
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
describe('People Groups Cloud Component', () => {
const loginSSOPage = new LoginPage();
const navigationBarPage = new NavigationBarPage();
const peopleGroupCloudComponentPage = new PeopleGroupCloudComponentPage();
const peopleCloudComponent = new PeopleCloudComponentPage();
const groupCloudComponentPage = new GroupCloudComponentPage();
const apiService = createApiService();
const identityService = new IdentityService(apiService);
const rolesService = new RolesService(apiService);
const groupIdentityService = new GroupIdentityService(apiService);
let apsUser;
let testUser;
let devopsUser;
let activitiUser;
let multipleRolesUser;
let noRoleUser;
let groupUser;
let groupAdmin;
let groupNoRole;
let groupMultipleRoles;
let apsUserRoleId: string;
let apsAdminRoleId: string;
let users = [];
let groups = [];
beforeAll(async () => {
await apiService.loginWithProfile('identityAdmin');
testUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
apsUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
activitiUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
devopsUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_DEVOPS]);
multipleRolesUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER, identityService.ROLES.ACTIVITI_ADMIN]);
noRoleUser = await identityService.createIdentityUser();
apsAdminRoleId = await rolesService.getRoleIdByRoleName(identityService.ROLES.ACTIVITI_ADMIN);
apsUserRoleId = await rolesService.getRoleIdByRoleName(identityService.ROLES.ACTIVITI_USER);
groupUser = await groupIdentityService.createIdentityGroup();
await groupIdentityService.assignRole(groupUser.id, apsUserRoleId, identityService.ROLES.ACTIVITI_USER);
groupAdmin = await groupIdentityService.createIdentityGroup();
await groupIdentityService.assignRole(groupAdmin.id, apsAdminRoleId, identityService.ROLES.ACTIVITI_ADMIN);
groupMultipleRoles = await groupIdentityService.createIdentityGroup();
await groupIdentityService.assignRole(groupMultipleRoles.id, apsAdminRoleId, identityService.ROLES.ACTIVITI_ADMIN);
await groupIdentityService.assignRole(groupMultipleRoles.id, apsUserRoleId, identityService.ROLES.ACTIVITI_USER);
groupNoRole = await groupIdentityService.createIdentityGroup();
users = [`${apsUser.idIdentityService}`, `${activitiUser.idIdentityService}`, `${noRoleUser.idIdentityService}`,
`${testUser.idIdentityService}`, `${devopsUser.idIdentityService}`, `${multipleRolesUser.idIdentityService}`];
groups = [`${groupUser.id}`, `${groupAdmin.id}`, `${groupNoRole.id}`, `${groupMultipleRoles.id}`];
await loginSSOPage.login(testUser.username, testUser.password);
});
afterAll(async () => {
await apiService.loginWithProfile('identityAdmin');
for (const user of users) {
await identityService.deleteIdentityUser(user);
}
for (const group of groups) {
await groupIdentityService.deleteIdentityGroup(group);
}
});
beforeEach(async () => {
await navigationBarPage.navigateToPeopleGroupCloudPage();
await peopleGroupCloudComponentPage.checkGroupsCloudComponentTitleIsDisplayed();
await peopleGroupCloudComponentPage.checkPeopleCloudComponentTitleIsDisplayed();
});
afterEach(async () => {
await browser.refresh();
});
describe('[C297674] Should be able to add filtering to People Cloud Component', () => {
beforeEach(async () => {
await peopleGroupCloudComponentPage.clickPeopleCloudMultipleSelection();
await peopleGroupCloudComponentPage.checkPeopleCloudMultipleSelectionIsSelected();
});
it('No role filtering', async () => {
await peopleCloudComponent.searchAssignee(noRoleUser.lastName);
await peopleCloudComponent.checkUserIsDisplayed(`${noRoleUser.firstName} ${noRoleUser.lastName}`);
await peopleCloudComponent.searchAssignee(apsUser.lastName);
await peopleCloudComponent.checkUserIsDisplayed(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.searchAssignee(testUser.lastName);
await peopleCloudComponent.checkUserIsDisplayed(`${testUser.firstName} ${testUser.lastName}`);
});
it('One role filtering', async () => {
await peopleGroupCloudComponentPage.enterPeopleRoles(`["${identityService.ROLES.ACTIVITI_USER}"]`);
await peopleCloudComponent.searchAssignee(apsUser.lastName);
await peopleCloudComponent.checkUserIsDisplayed(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.searchAssignee(devopsUser.lastName);
await peopleCloudComponent.checkNoResultsFoundError();
await peopleCloudComponent.searchAssignee(noRoleUser.lastName);
await peopleCloudComponent.checkNoResultsFoundError();
});
it('Multiple roles filtering', async () => {
await peopleGroupCloudComponentPage.enterPeopleRoles(`["${identityService.ROLES.ACTIVITI_USER}", "${identityService.ROLES.ACTIVITI_ADMIN}"]`);
await peopleCloudComponent.searchAssignee(multipleRolesUser.lastName);
await peopleCloudComponent.checkUserIsDisplayed(`${multipleRolesUser.firstName} ${multipleRolesUser.lastName}`);
await peopleCloudComponent.searchAssignee(apsUser.lastName);
await peopleCloudComponent.checkUserIsNotDisplayed(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.searchAssignee(testUser.lastName);
await peopleCloudComponent.checkUserIsNotDisplayed(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.searchAssignee(noRoleUser.lastName);
await peopleCloudComponent.checkNoResultsFoundError();
});
});
describe('[C309674] Should be able to add filtering to Group Cloud Component', () => {
beforeEach(async () => {
await peopleGroupCloudComponentPage.clickGroupCloudMultipleSelection();
});
it('No role filtering', async () => {
await peopleGroupCloudComponentPage.clearField(peopleGroupCloudComponentPage.groupRoleInput);
await groupCloudComponentPage.searchGroups(groupNoRole.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupNoRole.name);
await groupCloudComponentPage.searchGroups(groupAdmin.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupAdmin.name);
await groupCloudComponentPage.searchGroups(groupUser.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupUser.name);
});
it('One role filtering', async () => {
await peopleGroupCloudComponentPage.enterGroupRoles(`["${identityService.ROLES.ACTIVITI_ADMIN}"]`);
await groupCloudComponentPage.searchGroups(groupAdmin.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupAdmin.name);
await groupCloudComponentPage.searchGroups(groupUser.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupAdmin.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupUser.name);
await groupCloudComponentPage.searchGroups(groupNoRole.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupNoRole.name);
});
it('[C309996] Should be able to filter groups based on composite roles ACTIVITI_USER', async () => {
await peopleGroupCloudComponentPage.enterGroupRoles(`["${identityService.ROLES.ACTIVITI_USER}"]`);
await groupCloudComponentPage.searchGroups(groupAdmin.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupAdmin.name);
await groupCloudComponentPage.searchGroups(groupNoRole.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupNoRole.name);
await groupCloudComponentPage.searchGroups(groupUser.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupUser.name);
});
it('Multiple roles filtering', async () => {
await peopleGroupCloudComponentPage.enterGroupRoles(`["${identityService.ROLES.ACTIVITI_ADMIN}", "${identityService.ROLES.ACTIVITI_USER}"]`);
await groupCloudComponentPage.searchGroups(groupMultipleRoles.name);
await groupCloudComponentPage.checkGroupIsDisplayed(groupMultipleRoles.name);
await groupCloudComponentPage.searchGroups(groupAdmin.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupAdmin.name);
await groupCloudComponentPage.searchGroups(groupUser.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupUser.name);
await groupCloudComponentPage.searchGroups(groupNoRole.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupNoRole.name);
});
});
it('[C305033] Should fetch the preselect users based on the Validate flag set to True in Single mode selection', async () => {
await peopleGroupCloudComponentPage.clickPeopleCloudSingleSelection();
await peopleGroupCloudComponentPage.checkPeopleCloudSingleSelectionIsSelected();
await peopleGroupCloudComponentPage.enterPeoplePreselect('[{"id":"12345","username":"someUsername","email":"someEmail"}]');
await expect(await peopleCloudComponent.checkSelectedPeople('someUsername'));
await peopleGroupCloudComponentPage.clickPreselectValidation();
await expect(await peopleGroupCloudComponentPage.getPreselectValidationStatus()).toBe('true');
await peopleGroupCloudComponentPage.enterPeoplePreselect(`[{"email":"${apsUser.email}"}]`);
await expect(await peopleCloudComponent.checkSelectedPeople(`${apsUser.firstName} ${apsUser.lastName}`));
await peopleGroupCloudComponentPage.enterPeoplePreselect(`[{"username":"${testUser.username}"}]`);
await expect(await peopleCloudComponent.checkSelectedPeople(`${testUser.firstName} ${testUser.lastName}`));
});
it('[C309676] Should fetch the preselect users based on the Validate flag set to True in Multiple mode selection', async () => {
await peopleGroupCloudComponentPage.clickPeopleCloudMultipleSelection();
await peopleGroupCloudComponentPage.checkPeopleCloudMultipleSelectionIsSelected();
await peopleGroupCloudComponentPage.clickPreselectValidation();
await expect(await peopleGroupCloudComponentPage.getPreselectValidationStatus()).toBe('true');
await peopleGroupCloudComponentPage.enterPeoplePreselect(`[{"email":"${apsUser.email}"},{"email":"${testUser.email}"},{"email":"${noRoleUser.email}"}]`);
await peopleCloudComponent.checkSelectedPeople(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.checkSelectedPeople(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.checkSelectedPeople(`${noRoleUser.firstName} ${noRoleUser.lastName}`);
await peopleGroupCloudComponentPage.enterPeoplePreselect(`[{"username":"${apsUser.username}"},{"username":"${testUser.username}"},` +
`{"username":"${noRoleUser.username}"}]`);
await peopleCloudComponent.checkSelectedPeople(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.checkSelectedPeople(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.checkSelectedPeople(`${noRoleUser.firstName} ${noRoleUser.lastName}`);
await peopleCloudComponent.searchAssignee(noRoleUser.lastName);
await peopleCloudComponent.checkNoResultsFoundError();
});
it('[C309677] Should populate the Users without any validation when the Preselect flag is set to false', async () => {
await peopleGroupCloudComponentPage.clickPeopleCloudMultipleSelection();
await peopleGroupCloudComponentPage.checkPeopleCloudMultipleSelectionIsSelected();
await expect(await peopleGroupCloudComponentPage.getPreselectValidationStatus()).toBe('false');
await peopleGroupCloudComponentPage.enterPeoplePreselect(
`[{"id":"TestId1","firstName":"TestFirstName1","lastName":"TestLastName1"},` +
`{"id":"TestId2","firstName":"TestFirstName2","lastName":"TestLastName2"},` +
`{"id":"TestId3","firstName":"TestFirstName3","lastName":"TestLastName3"}]`);
await peopleCloudComponent.checkSelectedPeople('TestFirstName1 TestLastName1');
await peopleCloudComponent.checkSelectedPeople('TestFirstName2 TestLastName2');
await peopleCloudComponent.checkSelectedPeople('TestFirstName3 TestLastName3');
});
});
@@ -1,130 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { createApiService, GroupCloudComponentPage, GroupIdentityService, IdentityService, LoginPage, PeopleCloudComponentPage } from '@alfresco/adf-testing';
import { browser } from 'protractor';
import { PeopleGroupCloudComponentPage } from './../pages/people-group-cloud-component.page';
describe('People Groups Cloud Component', () => {
describe('People Groups Cloud Component', () => {
const loginSSOPage = new LoginPage();
const peopleGroupCloudComponentPage = new PeopleGroupCloudComponentPage();
const peopleCloudComponent = new PeopleCloudComponentPage();
const groupCloudComponentPage = new GroupCloudComponentPage();
const apiService = createApiService();
const identityService = new IdentityService(apiService);
const groupIdentityService = new GroupIdentityService(apiService);
let apsUser;
let testUser;
let noRoleUser;
let groupNoRole;
let users = [];
let hrGroup;
let testGroup;
beforeAll(async () => {
await apiService.loginWithProfile('identityAdmin');
hrGroup = await groupIdentityService.getGroupInfoByGroupName('hr');
testGroup = await groupIdentityService.getGroupInfoByGroupName('testgroup');
testUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
apsUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
await identityService.addUserToGroup(testUser.idIdentityService, testGroup.id);
await identityService.addUserToGroup(apsUser.idIdentityService, hrGroup.id);
noRoleUser = await identityService.createIdentityUser();
groupNoRole = await groupIdentityService.createIdentityGroup();
users = [apsUser.idIdentityService, noRoleUser.idIdentityService, testUser.idIdentityService];
await loginSSOPage.login(apsUser.username, apsUser.password);
});
afterAll(async () => {
await apiService.loginWithProfile('identityAdmin');
for (const user of users) {
await identityService.deleteIdentityUser(user);
}
await groupIdentityService.deleteIdentityGroup(groupNoRole.id);
});
beforeEach(async () => {
await peopleGroupCloudComponentPage.navigateTo();
});
it('[C305041] Should filter the People Single Selection with the Application name filter', async () => {
await peopleGroupCloudComponentPage.checkPeopleCloudSingleSelectionIsSelected();
await peopleGroupCloudComponentPage.enterPeopleAppName(browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name);
await peopleCloudComponent.searchAssignee(testUser.firstName);
await peopleCloudComponent.checkUserIsDisplayed(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.selectAssigneeFromList(`${testUser.firstName} ${testUser.lastName}`);
await expect(await peopleCloudComponent.checkSelectedPeople(`${testUser.firstName} ${testUser.lastName}`)).toBeTruthy(`${testUser.firstName} ${testUser.lastName} is not visible here!`);
});
it('[C305041] Should filter the People Multiple Selection with the Application name filter', async () => {
await peopleGroupCloudComponentPage.clickPeopleCloudMultipleSelection();
await peopleGroupCloudComponentPage.enterPeopleAppName(browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name);
await peopleCloudComponent.searchAssignee(testUser.firstName);
await peopleCloudComponent.checkUserIsDisplayed(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.selectAssigneeFromList(`${testUser.firstName} ${testUser.lastName}`);
await peopleCloudComponent.searchAssignee(apsUser.firstName);
await peopleCloudComponent.checkUserIsDisplayed(`${apsUser.firstName} ${apsUser.lastName}`);
await peopleCloudComponent.selectAssigneeFromList(`${apsUser.firstName} ${apsUser.lastName}`);
await expect(await peopleCloudComponent.checkSelectedPeople(`${apsUser.firstName} ${apsUser.lastName}`)).toBeTruthy(`${apsUser.firstName} ${apsUser.lastName} is not visible here!`);
await peopleCloudComponent.searchAssignee(noRoleUser.firstName);
await expect(await peopleCloudComponent.checkNoResultsFoundError()).toBeTruthy('There is something in the list!');
});
it('[C305041] Should filter the Groups Single Selection with the Application name filter', async () => {
await peopleGroupCloudComponentPage.clickGroupCloudSingleSelection();
await peopleGroupCloudComponentPage.enterGroupAppName(browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name);
await groupCloudComponentPage.searchGroups(hrGroup.name);
await groupCloudComponentPage.checkGroupIsDisplayed(hrGroup.name);
await groupCloudComponentPage.selectGroupFromList(hrGroup.name);
await expect(await groupCloudComponentPage.checkSelectedGroup(hrGroup.name)).toBeTruthy(`${hrGroup.name} is not visible here!`);
});
it('[C305041] Should filter the Groups Multiple Selection with the Application name filter', async () => {
await peopleGroupCloudComponentPage.clickGroupCloudMultipleSelection();
await peopleGroupCloudComponentPage.enterGroupAppName(browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name);
await groupCloudComponentPage.searchGroups(testGroup.name);
await groupCloudComponentPage.checkGroupIsDisplayed(testGroup.name);
await groupCloudComponentPage.selectGroupFromList(testGroup.name);
await groupCloudComponentPage.checkSelectedGroup(testGroup.name);
await expect(await groupCloudComponentPage.checkSelectedGroup(testGroup.name)).toBeTruthy(`${testGroup.name} is not visible here!`);
await groupCloudComponentPage.searchGroupsToExisting(hrGroup.name);
await groupCloudComponentPage.checkGroupIsDisplayed(hrGroup.name);
await groupCloudComponentPage.selectGroupFromList(hrGroup.name);
await groupCloudComponentPage.checkSelectedGroup(hrGroup.name);
await expect(await groupCloudComponentPage.checkSelectedGroup(hrGroup.name)).toBeTruthy(`${hrGroup.name} is not visible here!`);
await groupCloudComponentPage.searchGroupsToExisting(groupNoRole.name);
await groupCloudComponentPage.checkGroupIsNotDisplayed(groupNoRole.name);
});
});
});
+2 -1
View File
@@ -12,5 +12,6 @@
"C216430": "https://alfresco.atlassian.net/browse/ACS-4595",
"C280063": "https://alfresco.atlassian.net/browse/ACS-4595",
"C280064": "https://alfresco.atlassian.net/browse/ACS-4595",
"C280407": "https://alfresco.atlassian.net/browse/ACS-4595"
"C280407": "https://alfresco.atlassian.net/browse/ACS-4595",
"C277288": "https://alfresco.atlassian.net/browse/AAE-15475"
}
+9 -9
View File
@@ -155,7 +155,7 @@ describe('Search Radio Component', () => {
await searchFiltersPage.clickTypeFilterHeader();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(10);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(13);
await navigationBarPage.navigateToContentServices();
@@ -170,7 +170,7 @@ describe('Search Radio Component', () => {
await searchFiltersPage.clickTypeFilterHeader();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(10);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(13);
await navigationBarPage.navigateToContentServices();
jsonFile.categories[5].component.settings.pageSize = 9;
@@ -184,7 +184,7 @@ describe('Search Radio Component', () => {
await searchFiltersPage.clickTypeFilterHeader();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(9);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(12);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsNotDisplayed();
@@ -213,21 +213,21 @@ describe('Search Radio Component', () => {
await searchFiltersPage.clickTypeFilterHeader();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(5);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(8);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsNotDisplayed();
await searchFiltersPage.typeFiltersPage().clickShowMoreButton();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(10);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(13);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsNotDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().clickShowLessButton();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(5);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(8);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsNotDisplayed();
@@ -244,21 +244,21 @@ describe('Search Radio Component', () => {
await searchFiltersPage.clickTypeFilterHeader();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(5);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(8);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsNotDisplayed();
await searchFiltersPage.typeFiltersPage().clickShowMoreButton();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(10);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(13);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsNotDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().clickShowLessButton();
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(5);
await expect(await searchFiltersPage.typeFiltersPage().getRadioButtonsNumberOnPage()).toBe(8);
await searchFiltersPage.typeFiltersPage().checkShowMoreButtonIsDisplayed();
await searchFiltersPage.typeFiltersPage().checkShowLessButtonIsNotDisplayed();
+17
View File
@@ -176,6 +176,23 @@ export class SearchConfiguration {
]
}
}
},
{
id: 'createdModifiedDateRange',
name: 'Date',
enabled: true,
component: {
selector: 'date-range-advanced',
settings: {
dateFormat: 'dd-MMM-yy',
maxDate: 'today',
field: 'cm:created, cm:modified',
displayedLabelsByField: {
"cm:created": 'Created Date',
"cm:modified": 'Modified Date'
}
}
}
}
],
highlight: {
+16 -16
View File
@@ -9,7 +9,7 @@
"version": "6.2.0",
"license": "Apache-2.0",
"dependencies": {
"@alfresco/js-api": ">=6.2.0-982",
"@alfresco/js-api": ">=6.3.0-1031",
"commander": "^6.2.1",
"ejs": "^3.1.9",
"license-checker": "^25.0.1",
@@ -30,9 +30,9 @@
}
},
"node_modules/@alfresco/js-api": {
"version": "6.2.0-982",
"resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-6.2.0-982.tgz",
"integrity": "sha512-tP7/VblH0QOMAlhjzCW8n/kE9PXA2nwkPisalNVNVtvOa6jVnwMQQlVvfnCRKf+yXX7SQYBMTKbvMA9Io0gBqw==",
"version": "6.3.0-1035",
"resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-6.3.0-1035.tgz",
"integrity": "sha512-+1xjwpx+/+kTlVfbxT1znlGPEfWYPv6KpSNneIz51OH+sFJ030mtkWeU4OnTbgeypSR72BN+G+RMJia7QT6qfA==",
"dependencies": {
"event-emitter": "^0.3.5",
"superagent": "^6.0.0",
@@ -813,9 +813,9 @@
}
},
"node_modules/license-checker/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -930,9 +930,9 @@
}
},
"node_modules/normalize-package-data/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -1053,9 +1053,9 @@
}
},
"node_modules/read-installed/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -1212,9 +1212,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
+1 -1
View File
@@ -20,7 +20,7 @@
"dist": "rm -rf ../../dist/libs/cli && npm run build && cp -R ./bin ../../dist/libs/cli && cp -R ./resources ../../dist/libs/cli && cp -R ./templates ../../dist/libs/cli && cp ./package.json ../../dist/libs/cli"
},
"dependencies": {
"@alfresco/js-api": ">=6.2.0",
"@alfresco/js-api": ">=6.3.0-1054",
"commander": "^6.2.1",
"ejs": "^3.1.9",
"license-checker": "^25.0.1",
+1 -1
View File
@@ -21,7 +21,7 @@
"@angular/platform-browser": ">=14.1.3",
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=6.2.0",
"@alfresco/js-api": ">=6.3.0-1054",
"@ngx-translate/core": ">=14.0.0",
"moment": ">=2.22.2",
"@alfresco/adf-core": ">=6.2.0"
@@ -16,7 +16,6 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { setupTestBed } from '@alfresco/adf-core';
import { NodesApiService } from '../common/services/nodes-api.service';
import { ContentTestingModule } from '../testing/content.testing.module';
import { TranslateModule } from '@ngx-translate/core';
@@ -110,12 +109,14 @@ describe('AspectListComponent', () => {
let aspectListService: AspectListService;
let nodeService: NodesApiService;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [AspectListService]
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [AspectListService]
});
});
describe('Loading', () => {
@@ -15,7 +15,6 @@
* limitations under the License.
*/
import { setupTestBed } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { DialogAspectListService } from '@alfresco/adf-content-services';
@@ -27,14 +26,13 @@ describe('DialogAspectListService', () => {
let dialogAspectListService: DialogAspectListService;
let dialog: MatDialog;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
dialogAspectListService = TestBed.inject(DialogAspectListService);
dialog = TestBed.inject(MatDialog);
});
@@ -18,7 +18,6 @@
import { MinimalNode } from '@alfresco/js-api';
import { TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { setupTestBed } from '@alfresco/adf-core';
import { NodesApiService } from '../../common/services/nodes-api.service';
import { EMPTY, of } from 'rxjs';
import { ContentTestingModule } from '../../testing/content.testing.module';
@@ -34,14 +33,13 @@ describe('NodeAspectService', () => {
let nodeApiService: NodesApiService;
let cardViewContentUpdateService: CardViewContentUpdateService;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
dialogAspectListService = TestBed.inject(DialogAspectListService);
nodeAspectService = TestBed.inject(NodeAspectService);
nodeApiService = TestBed.inject(NodesApiService);
@@ -16,7 +16,7 @@
*/
import { AuditService } from './audit.service';
import { AppConfigService, setupTestBed } from '@alfresco/adf-core';
import { AppConfigService } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
import { ContentTestingModule } from '../testing/content.testing.module';
import { TestBed } from '@angular/core/testing';
@@ -26,14 +26,13 @@ declare let jasmine: any;
describe('AuditService', () => {
let service: AuditService;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
const appConfig: AppConfigService = TestBed.inject(AppConfigService);
appConfig.config = {
ecmHost: 'http://localhost:9876/ecm',
@@ -18,7 +18,6 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Node } from '@alfresco/js-api';
import { setupTestBed } from '@alfresco/adf-core';
import { fakeNodeWithCreatePermission } from '../mock';
import { DocumentListComponent, DocumentListService } from '../document-list';
import { BreadcrumbComponent } from './breadcrumb.component';
@@ -36,16 +35,15 @@ describe('Breadcrumb', () => {
});
let documentListComponent: DocumentListComponent;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers : [{ provide: DocumentListService, useValue: documentListService }]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers : [{ provide: DocumentListService, useValue: documentListService }]
});
fixture = TestBed.createComponent(BreadcrumbComponent);
component = fixture.componentInstance;
documentListComponent = TestBed.createComponent<DocumentListComponent>(DocumentListComponent).componentInstance;
@@ -18,7 +18,6 @@
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { setupTestBed } from '@alfresco/adf-core';
import { fakeNodeWithCreatePermission } from '../mock';
import { DocumentListComponent, DocumentListService } from '../document-list';
import { DropdownBreadcrumbComponent } from './dropdown-breadcrumb.component';
@@ -33,16 +32,15 @@ describe('DropdownBreadcrumb', () => {
let documentList: DocumentListComponent;
let documentListService: DocumentListService = jasmine.createSpyObj({ loadFolderByNodeId: of(''), isCustomSourceService: false });
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: DocumentListService, useValue: documentListService }]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: DocumentListService, useValue: documentListService }]
});
fixture = TestBed.createComponent(DropdownBreadcrumbComponent);
component = fixture.componentInstance;
documentList = TestBed.createComponent<DocumentListComponent>(DocumentListComponent).componentInstance;
@@ -1,8 +1,17 @@
<div class="adf-categories-management">
<p *ngIf="!categories.length && !categoryNameControlVisible"
class="adf-no-categories-message">
{{ noCategoriesMsg | translate }}
</p>
<div
class="adf-category-name-field">
<input #categoryNameInput
matInput
autocomplete="off"
[formControl]="categoryNameControl"
(keyup.enter)="addCategory()"
aria-labelledby="adf-category-name-input-label"
placeholder="{{'CATEGORIES_MANAGEMENT.INPUT_PLACEHOLDER' | translate }}"
adf-auto-focus />
<mat-error [hidden]="!categoryNameControl.invalid">{{ categoryNameErrorMessageKey | translate }}</mat-error>
</div>
<div class="adf-categories-list"
[class.adf-categories-list-fixed]="!categoryNameControlVisible">
<span
@@ -21,33 +30,10 @@
</button>
</span>
</div>
<div *ngIf="((!categoryNameControlVisible && categories.length)) || categoryNameControlVisible"
[hidden]="!categoryNameControlVisible"
class="adf-category-name-field">
<mat-form-field>
<mat-icon matPrefix>search</mat-icon>
<mat-label id="adf-category-name-input-label">
{{ 'CATEGORIES_MANAGEMENT.NAME' | translate }}
</mat-label>
<input
#categoryNameInput
matInput
autocomplete="off"
[formControl]="categoryNameControl"
(keyup.enter)="addCategory()"
aria-labelledby="adf-category-name-input-label"
adf-auto-focus
/>
<mat-error [hidden]="!categoryNameControl.invalid">{{ categoryNameErrorMessageKey | translate }}</mat-error>
</mat-form-field>
<button
mat-icon-button
[class.adf-btn-padded]="!isCRUDMode"
(click)="hideNameInput()"
[attr.title]="'CATEGORIES_MANAGEMENT.HIDE_INPUT' | translate">
<mat-icon>remove</mat-icon>
</button>
</div>
<p *ngIf="!categories.length && !categoryNameControlVisible"
class="adf-no-categories-message">
{{ noCategoriesMsg | translate }}
</p>
</div>
<div class="adf-existing-categories-panel" *ngIf="existingCategoriesPanelVisible">
<ng-container *ngIf="isCRUDMode && (!existingCategoriesLoading || existingCategories)">
@@ -57,7 +43,7 @@
{{ 'CATEGORIES_MANAGEMENT.GENERIC_CREATE' | translate : { name: categoryNameControl.value } }}
</span>
</ng-container>
<div *ngIf="categoryNameControlVisible" class="adf-categories-list">
<div class="adf-categories-list">
<ng-container *ngIf="!existingCategoriesLoading && existingCategories">
<p class="adf-existing-categories-label">
{{ existingCategoriesMsg | translate }}
@@ -1,8 +1,15 @@
.adf-categories-management {
padding-top: 12px;
.adf-category-name-field {
display: flex;
justify-content: space-between;
width: 100%;
background: var(--adf-metadata-tags-background-color);
height: 32px;
border-radius: 12px;
align-items: center;
padding: 0 12px;
mat-form-field {
width: 100%;
@@ -34,7 +41,6 @@
}
.adf-categories-list {
padding-bottom: 10px;
.mat-list-base .mat-list-item,
.mat-list-base .mat-list-option {
@@ -167,38 +167,11 @@ describe('CategoriesManagementComponent', () => {
component.categoryNameControlVisible = true;
fixture.detectChanges();
});
it('should be hidden initially', () => {
component.categoryNameControlVisible = false;
fixture.detectChanges();
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
expect(categoryControl.hidden).toBeTrue();
});
it('should be visible when categoryNameControlVisible is true', () => {
const categoryControl = fixture.debugElement.query(By.css('.adf-category-name-field'));
expect(categoryControl).toBeTruthy();
});
it('should have correct label and hide button', () => {
const categoryControlLabel = fixture.debugElement.query(By.css('#adf-category-name-input-label')).nativeElement;
const categoryControlHideBtn: HTMLButtonElement = fixture.debugElement.query(By.css('.adf-category-name-field button')).nativeElement;
expect(categoryControlHideBtn).toBeTruthy();
expect(categoryControlHideBtn.attributes.getNamedItem('title').textContent.trim()).toBe('CATEGORIES_MANAGEMENT.HIDE_INPUT');
expect(categoryControlLabel.textContent.trim()).toBe('CATEGORIES_MANAGEMENT.NAME');
});
it('should hide category control and existing categories panel on clicking hide button', () => {
const categoryControlHideBtn: HTMLButtonElement = fixture.debugElement.query(By.css('.adf-category-name-field button')).nativeElement;
const controlVisibilityChangeSpy = spyOn(component.categoryNameControlVisibleChange, 'emit').and.callThrough();
categoryControlHideBtn.click();
fixture.detectChanges();
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
expect(categoryControl.hidden).toBeTrue();
expect(component.categoryNameControlVisible).toBeFalse();
expect(component.existingCategoriesPanelVisible).toBeFalse();
expect(controlVisibilityChangeSpy).toHaveBeenCalledOnceWith(false);
});
});
describe('Spinner', () => {
@@ -415,9 +388,7 @@ describe('CategoriesManagementComponent', () => {
it('should clear and hide input after category is created', fakeAsync(() => {
const controlVisibilityChangeSpy = spyOn(component.categoryNameControlVisibleChange, 'emit');
createCategory('test');
const categoryControl: HTMLDivElement = fixture.debugElement.query(By.css('.adf-category-name-field')).nativeElement;
expect(categoryControl.hidden).toBeTrue();
expect(controlVisibilityChangeSpy).toHaveBeenCalledOnceWith(false);
expect(getExistingCategoriesList()).toEqual([]);
expect(component.categoryNameControl.value).toBe('');
@@ -484,4 +455,15 @@ describe('CategoriesManagementComponent', () => {
}));
});
});
it('should remove a category', fakeAsync(() => {
component.managementMode = CategoriesManagementMode.ASSIGN;
const categoryToRemove: Category = { id: 'catToRemove', name: 'Category to Remove' };
component.categories = [categoryToRemove];
component['_existingCategories'] = [];
component.initialCategories = [];
component.removeCategoryTitle = 'Remove Category';
component.removeCategory(categoryToRemove);
expect(component.categories.length).toBe(0);
}));
});
@@ -83,9 +83,7 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
set categoryNameControlVisible(categoryNameControlVisible: boolean) {
this._categoryNameControlVisible = categoryNameControlVisible;
if (categoryNameControlVisible) {
setTimeout(() => {
this.categoryNameInputElement.nativeElement.scrollIntoView();
});
this._existingCategoriesPanelVisible = true;
} else {
this._existingCategoriesPanelVisible = false;
@@ -17,7 +17,7 @@
import { TestBed } from '@angular/core/testing';
import { ContentService } from './content.service';
import { AppConfigService, AuthenticationService, StorageService, setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
import { AppConfigService, AuthenticationService, StorageService, CoreTestingModule } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { TranslateModule } from '@ngx-translate/core';
@@ -32,14 +32,13 @@ describe('ContentService', () => {
const nodeId = 'fake-node-id';
setupTestBed({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
});
authService = TestBed.inject(AuthenticationService);
contentService = TestBed.inject(ContentService);
storage = TestBed.inject(StorageService);
@@ -20,7 +20,7 @@ import { from, Observable, throwError, Subject } from 'rxjs';
import { catchError, map, switchMap, filter, take } from 'rxjs/operators';
import { RepositoryInfo, SystemPropertiesRepresentation } from '@alfresco/js-api';
import { BpmProductVersionModel, AlfrescoApiService, AuthenticationService } from '@alfresco/adf-core';
import { BpmProductVersionModel, AuthenticationService } from '@alfresco/adf-core';
import { ApiClientsService } from '@alfresco/adf-core/api';
@Injectable({
@@ -34,13 +34,12 @@ export class DiscoveryApiService {
ecmProductInfo$ = new Subject<RepositoryInfo>();
constructor(
private apiService: AlfrescoApiService,
private authenticationService: AuthenticationService,
private apiClientsService: ApiClientsService
) {
this.authenticationService.onLogin
.pipe(
filter(() => this.apiService.getInstance()?.isEcmLoggedIn()),
filter(() => this.authenticationService.isEcmLoggedIn()),
take(1),
switchMap(() => this.getEcmProductInfo())
)
@@ -16,24 +16,22 @@
*/
import { TestBed } from '@angular/core/testing';
import { AppConfigService, setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
import { AppConfigService, CoreTestingModule } from '@alfresco/adf-core';
import { SitesService } from './sites.service';
import { TranslateModule } from '@ngx-translate/core';
declare let jasmine: any;
describe('Sites service', () => {
let service;
setupTestBed({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
});
let service: SitesService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule
]
});
const appConfig: AppConfigService = TestBed.inject(AppConfigService);
appConfig.config = {
ecmHost: 'http://localhost:9876/ecm',
@@ -45,7 +45,8 @@ export class SitesService {
return this._sitesApi;
}
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
constructor(private apiService: AlfrescoApiService,
private logService: LogService) {
}
/**
@@ -140,15 +141,6 @@ export class SitesService {
return from(this.sitesApi.listSiteMemberships(siteId, opts));
}
/**
* Gets the username of the user currently logged into ACS.
*
* @returns Username string
*/
getEcmCurrentLoggedUserName(): string {
return this.apiService.getInstance().getEcmUsername();
}
/**
* Looks for a site inside the path of a Node and returns its guid if it finds one.
* (return an empty string if no site is found)
@@ -17,7 +17,7 @@
import { EventEmitter } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { AppConfigModule, AppConfigService, setupTestBed, CoreTestingModule } from '@alfresco/adf-core';
import { AppConfigModule, AppConfigService, CoreTestingModule } from '@alfresco/adf-core';
import { UploadService } from './upload.service';
import { RepositoryInfo } from '@alfresco/js-api';
import { TranslateModule } from '@ngx-translate/core';
@@ -34,23 +34,22 @@ describe('UploadService', () => {
const mockProductInfo = new BehaviorSubject<RepositoryInfo>(null);
setupTestBed({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
AppConfigModule
],
providers: [
{
provide: DiscoveryApiService,
useValue: {
ecmProductInfo$: mockProductInfo
}
}
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
CoreTestingModule,
AppConfigModule
],
providers: [
{
provide: DiscoveryApiService,
useValue: {
ecmProductInfo$: mockProductInfo
}
}
]
});
appConfigService = TestBed.inject(AppConfigService);
appConfigService.config = {
ecmHost: 'http://localhost:9876/ecm',
@@ -9,8 +9,8 @@
[multi]="multi"
[displayAspect]="displayAspect"
[preset]="preset"
[displayTags]="true"
[displayCategories]="true">
[displayTags]="displayTags"
[displayCategories]="displayCategories">
</adf-content-metadata>
</mat-card-content>
<mat-card-footer class="adf-content-metadata-card-footer">
@@ -23,24 +23,6 @@
data-automation-id="meta-data-card-edit-aspect">
<mat-icon>menu</mat-icon>
</button>
<button *ngIf="!readOnly && hasAllowableOperations()"
mat-icon-button
(click)="toggleEdit()"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-edit">
<mat-icon>mode_edit</mat-icon>
</button>
</div>
<button *ngIf="displayDefaultProperties" mat-button (click)="toggleExpanded()" data-automation-id="meta-data-card-toggle-expand">
<ng-container *ngIf="!expanded">
<span data-automation-id="meta-data-card-toggle-expand-label">{{ 'ADF_VIEWER.SIDEBAR.METADATA.MORE_INFORMATION' | translate }}</span>
<mat-icon>keyboard_arrow_down</mat-icon>
</ng-container>
<ng-container *ngIf="expanded">
<span data-automation-id="meta-data-card-toggle-expand-label">{{ 'ADF_VIEWER.SIDEBAR.METADATA.LESS_INFORMATION' | translate }}</span>
<mat-icon>keyboard_arrow_up</mat-icon>
</ng-container>
</button>
</mat-card-footer>
</mat-card>
@@ -20,7 +20,6 @@ import { By } from '@angular/platform-browser';
import { Node } from '@alfresco/js-api';
import { ContentMetadataCardComponent } from './content-metadata-card.component';
import { ContentMetadataComponent } from '../content-metadata/content-metadata.component';
import { setupTestBed } from '@alfresco/adf-core';
import { ContentTestingModule } from '../../../testing/content.testing.module';
import { SimpleChange } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
@@ -38,14 +37,13 @@ describe('ContentMetadataCardComponent', () => {
const preset = 'custom-preset';
let nodeAspectService: NodeAspectService = null;
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
]
});
fixture = TestBed.createComponent(ContentMetadataCardComponent);
contentMetadataService = TestBed.inject(ContentMetadataService);
component = fixture.componentInstance;
@@ -147,72 +145,6 @@ describe('ContentMetadataCardComponent', () => {
expect(contentMetadataComponent).toBeNull();
});
it('should toggle editable by clicking on the button', () => {
component.editable = true;
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
button.triggerEventHandler('click', {});
fixture.detectChanges();
expect(component.editable).toBe(false);
});
it('should toggle expanded by clicking on the button', () => {
component.expanded = true;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand"]'));
button.triggerEventHandler('click', {});
fixture.detectChanges();
expect(component.expanded).toBe(false);
});
it('should have the proper text on button while collapsed', () => {
component.expanded = false;
fixture.detectChanges();
const buttonLabel = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand-label"]'));
expect(buttonLabel.nativeElement.innerText.trim()).toBe('ADF_VIEWER.SIDEBAR.METADATA.MORE_INFORMATION');
});
it('should have the proper text on button while collapsed', () => {
component.expanded = true;
fixture.detectChanges();
const buttonLabel = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-expand-label"]'));
expect(buttonLabel.nativeElement.innerText.trim()).toBe('ADF_VIEWER.SIDEBAR.METADATA.LESS_INFORMATION');
});
it('should hide the edit button in readOnly is true', () => {
component.readOnly = true;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).toBeNull();
});
it('should hide the edit button if node does not have `update` permissions', () => {
component.readOnly = false;
component.node.allowableOperations = null;
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).toBeNull();
});
it('should show the edit button if node does has `update` permissions', () => {
component.readOnly = false;
component.node.allowableOperations = [AllowableOperationsEnum.UPDATE];
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('[data-automation-id="meta-data-card-toggle-edit"]'));
expect(button).not.toBeNull();
});
it('should expand the card when custom display aspect is valid', () => {
expect(component.expanded).toBeFalsy();
@@ -48,6 +48,14 @@ export class ContentMetadataCardComponent implements OnChanges {
@Input()
displayAspect: string = null;
/** Display tags in the card **/
@Input()
displayTags = true;
/** Display categories in the card **/
@Input()
displayCategories = true;
/** (required) Name or configuration of the metadata preset, which defines aspects
* and their properties.
*/
@@ -101,14 +109,6 @@ export class ContentMetadataCardComponent implements OnChanges {
this.expanded = !this._displayDefaultProperties;
}
toggleEdit(): void {
this.editable = !this.editable;
}
toggleExpanded(): void {
this.expanded = !this.expanded;
}
hasAllowableOperations() {
return this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.UPDATE);
}
@@ -1,131 +1,171 @@
<div class="adf-metadata-properties">
<mat-accordion displayMode="flat"
[multi]="multi">
<mat-expansion-panel *ngIf="displayDefaultProperties"
[expanded]="canExpandProperties()"
[attr.data-automation-id]="'adf-metadata-group-properties'">
<mat-accordion displayMode="flat" [multi]="multi">
<mat-expansion-panel *ngIf="displayDefaultProperties" [expanded]="true"
[attr.data-automation-id]="'adf-metadata-group-properties'" (opened)="generalInfoPanelState = true"
(closed)="generalInfoPanelState = false" hideToggle>
<mat-expansion-panel-header>
<mat-panel-title class="adf-metadata-properties-title">
{{ 'CORE.METADATA.BASIC.HEADER' | translate }}
</mat-panel-title>
<div class="adf-toggle-icons">
<mat-icon>
{{ generalInfoPanelState ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">
{{ 'CORE.METADATA.HEADER_TITLE' | translate }}
</mat-panel-title>
</div>
<button *ngIf="!editableGeneralInfo" mat-icon-button (click)="toggleGeneralEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-generalInfo-edit" class="adf-edit-icon-buttons">
<mat-icon>mode_edit</mat-icon>
</button>
<div class="adf-metadata-action-buttons" *ngIf="editableGeneralInfo">
<button mat-icon-button (click)="cancelGeneralInfoChanges($event)"
data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button (click)="saveGeneralInfoChanges($event)" color="primary"
data-automation-id="save-generalInfo-metadata" [disabled]="!hasMetadataChanged">
<mat-icon>check</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<adf-card-view
(keydown)="keyDown($event)"
[properties]="basicProperties$ | async"
[editable]="editable"
[displayEmpty]="displayEmpty"
<mat-divider class="adf-mat-divider"></mat-divider>
<adf-card-view (keydown)="keyDown($event)" [properties]="basicProperties$ | async"
[editableGeneralInfo]="editableGeneralInfo" [displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
<ng-container *ngIf="displayTags">
<mat-expansion-panel *ngIf="!editable">
<mat-expansion-panel (opened)="tagsPanelState = true" (closed)="tagsPanelState = false" hideToggle
[expanded]="tagsPanelState">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'METADATA.BASIC.TAGS' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</p>
</mat-expansion-panel>
<div
*ngIf="editable"
class="adf-metadata-properties-tags">
<div class="adf-metadata-properties-tags-title">
<p>{{ 'METADATA.BASIC.TAGS' | translate }}</p>
<button
data-automation-id="showing-tag-input-button"
mat-icon-button
[attr.title]="'METADATA.BASIC.ADD_TAG_TOOLTIP' | translate"
(click)="tagNameControlVisible = true"
[hidden]="tagNameControlVisible || saving">
<mat-icon>add</mat-icon>
<div class="adf-toggle-icons">
<mat-icon>
{{ tagsPanelState ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">{{ 'METADATA.BASIC.TAGS' | translate
}}</mat-panel-title>
</div>
<button *ngIf="!editableTags" mat-icon-button (click)="toggleTagsEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-tags-edit" class="adf-edit-icon-buttons">
<mat-icon>mode_edit</mat-icon>
</button>
<div class="adf-metadata-action-buttons" *ngIf="editableTags">
<button mat-icon-button (click)="CancelTagsChanges($event)" data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button (click)="saveTagsChanges($event)" color="primary"
data-automation-id="save-tags-metadata" [disabled]="!hasMetadataChanged">
<mat-icon>check</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<mat-divider class="adf-mat-divider"></mat-divider>
<div *ngIf="!editableTags">
<span *ngFor="let tag of tags" class="adf-metadata-properties-tag">{{ tag }}</span>
</div>
<adf-tags-creator
[(tagNameControlVisible)]="tagNameControlVisible"
(tagsChange)="storeTagsToAssign($event)"
[mode]="tagsCreatorMode"
[tags]="assignedTags"
[disabledTagsRemoving]="saving">
</adf-tags-creator>
</div>
<div *ngIf="!tags.length && !editableTags" class="adf-metadata-no-tags-added">
{{ 'METADATA.BASIC.NO_TAGS_ADDED' | translate }}
</div>
<div *ngIf="editableTags" class="adf-metadata-properties-tags">
<adf-tags-creator [(tagNameControlVisible)]="tagNameControlVisible"
(tagsChange)="storeTagsToAssign($event)" [mode]="tagsCreatorMode" [tags]="assignedTags"
[disabledTagsRemoving]="saving">
</adf-tags-creator>
</div>
</mat-expansion-panel>
</ng-container>
<ng-container *ngIf="displayCategories">
<mat-expansion-panel *ngIf="!editable">
<mat-expansion-panel (opened)="categoriesPanelState = true" (closed)="categoriesPanelState = false"
hideToggle [expanded]="categoriesPanelState">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
</mat-expansion-panel>
<div *ngIf="editable"
class="adf-metadata-categories-header">
<div class="adf-metadata-categories-title">
<p>{{ 'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' | translate }}</p>
<button
mat-icon-button
[attr.title]="'CATEGORIES_MANAGEMENT.ASSIGN_CATEGORIES' | translate"
[hidden]="categoryControlVisible || saving"
(click)="categoryControlVisible = true">
<mat-icon>add</mat-icon>
<div class="adf-toggle-icons">
<mat-icon>
{{ categoriesPanelState ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">{{
'CATEGORIES_MANAGEMENT.CATEGORIES_TITLE' |
translate }}</mat-panel-title>
</div>
<button *ngIf="!editableCategories" mat-icon-button (click)="toggleCategoriesEdit($event)"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-categoeies-edit" class="adf-edit-icon-buttons">
<mat-icon>mode_edit</mat-icon>
</button>
<div class="adf-metadata-action-buttons" *ngIf="editableCategories">
<button mat-icon-button (click)="cancelCategoriesChanges($event)"
data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button (click)="saveCategoriesChanges($event)" color="primary"
data-automation-id="save-categories-metadata" [disabled]="!hasMetadataChanged">
<mat-icon>check</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<mat-divider class="adf-mat-divider"></mat-divider>
<div *ngIf="!editableCategories">
<p *ngFor="let category of categories" class="adf-metadata-categories">{{ category.name }}</p>
</div>
<adf-categories-management
[(categoryNameControlVisible)]="categoryControlVisible"
[disableRemoval]="saving"
[categories]="categories"
[managementMode]="categoriesManagementMode"
[classifiableChanged]="classifiableChanged"
(categoriesChange)="storeCategoriesToAssign($event)">
</adf-categories-management>
</div>
<div *ngIf="!categories.length && !editableCategories" class="adf-metadata-no-catagories-added">
{{ 'CATEGORIES_MANAGEMENT.NO_CATEGORIES_ADDED' | translate }}
</div>
<div *ngIf="editableCategories" class="adf-metadata-categories-header">
<adf-categories-management [(categoryNameControlVisible)]="categoryControlVisible"
[disableRemoval]="saving" [categories]="categories" [managementMode]="categoriesManagementMode"
[classifiableChanged]="classifiableChanged"
(categoriesChange)="storeCategoriesToAssign($event)">
</adf-categories-management>
</div>
</mat-expansion-panel>
</ng-container>
<ng-container *ngIf="expanded">
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
<div *ngFor="let group of groupedProperties; let first = first;"
class="adf-metadata-grouped-properties-container">
<mat-expansion-panel *ngIf="showGroup(group) || editable"
[attr.data-automation-id]="'adf-metadata-group-' + group.title"
[expanded]="canExpandTheCard(group) || !displayDefaultProperties && first">
<mat-expansion-panel-header>
<mat-panel-title>
<ng-container *ngIf="groupedProperties$ | async; else loading; let groupedProperties">
<div *ngFor="let group of groupedProperties; let first = first;"
class="adf-metadata-grouped-properties-container">
<mat-expansion-panel [attr.data-automation-id]="'adf-metadata-group-' + group.title"
[expanded]="group.expanded" (opened)="group.expanded= true" (closed)="group.expanded= false"
hideToggle>
<mat-expansion-panel-header>
<div class="adf-toggle-icons">
<mat-icon>
{{ group.expanded || aspectPanelstate ? 'expand_more' : 'chevron_right'}}</mat-icon>
<mat-panel-title class="adf-metadata-properties-title">
{{ group.title | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<adf-card-view
(keydown)="keyDown($event)"
[properties]="group.properties"
[editable]="editable"
[displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
</div>
</ng-container>
<ng-template #loading>
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
</mat-progress-bar>
</ng-template>
</div>
<button *ngIf="!group.editable" mat-icon-button
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
data-automation-id="meta-data-card-toggle-edit" class="adf-edit-icon-buttons"
(click)="toggleEdit(group, $event)">
<mat-icon>mode_edit</mat-icon>
</button>
<div class="adf-metadata-action-buttons" *ngIf="group.editable">
<button mat-icon-button (click)="cancelGroupChanges(group, $event)"
data-automation-id="reset-metadata">
<mat-icon>clear</mat-icon>
</button>
<button mat-icon-button (click)="saveGroupChanges(group, $event)" color="primary"
data-automation-id="save-metadata" [disabled]="!hasMetadataChanged">
<mat-icon>check</mat-icon>
</button>
</div>
</mat-expansion-panel-header>
<mat-divider class="adf-mat-divider"></mat-divider>
<adf-card-view (keydown)="keyDown($event)" [properties]="group.properties"
[editable]="group.editable" [displayEmpty]="displayEmpty"
[copyToClipboardAction]="copyToClipboardAction"
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
[multiValueSeparator]="multiValueSeparator">
</adf-card-view>
</mat-expansion-panel>
</div>
</ng-container>
<ng-template #loading>
<mat-progress-bar mode="indeterminate" [attr.aria-label]="'DATA_LOADING' | translate">
</mat-progress-bar>
</ng-template>
</mat-accordion>
<div class="adf-metadata-action-buttons"
*ngIf="editable">
<button mat-button
(click)="cancelChanges()"
data-automation-id="reset-metadata"
[disabled]="!hasMetadataChanged">
{{ 'CORE.METADATA.ACTIONS.CANCEL' | translate }}
</button>
<button mat-raised-button
(click)="saveChanges()"
color="primary"
data-automation-id="save-metadata"
[disabled]="!hasMetadataChanged">
{{ 'CORE.METADATA.ACTIONS.SAVE' | translate }}
</button>
</div>
</div>
@@ -1,37 +1,71 @@
.adf {
&-metadata-properties {
.mat-expansion-panel-header.mat-expanded:hover,
.mat-expansion-panel-header.mat-expanded:focus {
background: var(--adf-theme-background-hover-color);
}
.mat-expansion-panel {
border: 1px solid var(--adf-metadata-property-panel-border-color);
border-radius: 12px !important;
margin-bottom: 12px;
mat-expansion-panel-header {
height: 64px;
height: 56px;
.adf-metadata-properties-title {
font-weight: normal;
font-size: 15px;
padding-left: 12px;
}
}
}
.mat-expansion-panel:not([class*='mat-elevation-z']) {
box-shadow: none;
}
.adf-metadata-properties-tag {
height: 40px;
.adf-mat-divider {
margin-left: -24px;
margin-right: -24px;
}
.adf-edit-icon-buttons {
color: var(--adf-theme-foreground-text-color-054);
}
.adf-toggle-icons {
display: flex;
align-items: center;
margin-top: -14px;
margin-bottom: 1em;
flex: 1;
}
&:first-of-type {
margin-top: 5px;
}
.adf-metadata-properties-tag {
height: 32px;
display: inline-flex;
align-items: center;
border-radius: 16px;
width: fit-content;
background: var(--adf-metadata-tags-background-color);
margin-top: 12px;
padding: 6px 12px;
justify-content: center;
margin-left: 8px;
}
.adf-metadata-no-tags-added {
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
padding: 24px;
}
.adf-metadata-no-catagories-added {
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
padding: 24px;
}
&-tags {
padding: 0 10px 0 26px;
&-title {
display: flex;
@@ -42,15 +76,9 @@
}
adf-tags-creator {
margin-top: 19px;
.adf-tags-creation {
padding-right: 0;
padding-left: 12px;
.adf-tag {
margin-top: -14px;
}
}
&.adf-creator-with-existing-tags-panel {
@@ -73,7 +101,7 @@
&-metadata-categories-header {
display: flex;
flex-direction: column;
padding: 0 24px;
padding-right: 24px;
.adf-metadata-categories-title {
display: flex;
@@ -92,3 +120,24 @@
}
}
}
.acs-details-container {
.mat-tab-body-content {
.adf-content-metadata-card {
.adf-metadata-properties {
.mat-expansion-panel {
width: 755px;
border: 1px solid var(--adf-metadata-property-panel-border-color);
margin: 24px;
border-radius: 12px !important;
}
}
}
}
}
.adf-content-metadata-card {
.mat-card:not([class*=mat-elevation-z]) {
box-shadow: none;
}
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';
import { ComponentFixture, TestBed, tick, fakeAsync, discardPeriodicTasks, flush } from '@angular/core/testing';
import { DebugElement, SimpleChange } from '@angular/core';
import { By } from '@angular/platform-browser';
import { Category, CategoryPaging, ClassesApi, MinimalNode, Node, Tag, TagBody, TagEntry, TagPaging, TagPagingList } from '@alfresco/js-api';
@@ -23,7 +23,7 @@ import { ContentMetadataComponent } from './content-metadata.component';
import { ContentMetadataService } from '../../services/content-metadata.service';
import {
CardViewBaseItemModel, CardViewComponent,
LogService, setupTestBed, AppConfigService, UpdateNotification
LogService, AppConfigService, UpdateNotification
} from '@alfresco/adf-core';
import { NodesApiService } from '../../../common/services/nodes-api.service';
import { throwError, of, EMPTY } from 'rxjs';
@@ -34,6 +34,9 @@ import { CardViewContentUpdateService } from '../../../common/services/card-view
import { PropertyGroup } from '../../interfaces/property-group.interface';
import { PropertyDescriptorsService } from '../../services/property-descriptors.service';
import { CategoriesManagementComponent, CategoriesManagementMode, CategoryService, TagsCreatorComponent, TagsCreatorMode, TagService } from '@alfresco/adf-content-services';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatDividerModule } from '@angular/material/divider';
describe('ContentMetadataComponent', () => {
let component: ContentMetadataComponent;
@@ -100,37 +103,40 @@ describe('ContentMetadataComponent', () => {
return fixture.debugElement.query(By.css('.adf-metadata-categories-title button')).nativeElement;
}
setupTestBed({
imports: [
TranslateModule.forRoot(),
ContentTestingModule
],
providers: [
{
provide: LogService,
useValue: {
error: jasmine.createSpy('error')
}
},
{
provide: TagService,
useValue: {
getTagsByNodeId: () => EMPTY,
removeTag: () => EMPTY,
assignTagsToNode: () => EMPTY
}
},
{
provide: CategoryService,
useValue: {
getCategoryLinksForNode: () => EMPTY,
linkNodeToCategory: () => EMPTY,
unlinkNodeFromCategory: () => EMPTY
}
}]
});
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
ContentTestingModule,
MatIconModule,
MatExpansionModule,
MatDividerModule
],
providers: [
{
provide: LogService,
useValue: {
error: jasmine.createSpy('error')
}
},
{
provide: TagService,
useValue: {
getTagsByNodeId: () => EMPTY,
removeTag: () => EMPTY,
assignTagsToNode: () => EMPTY
}
},
{
provide: CategoryService,
useValue: {
getCategoryLinksForNode: () => EMPTY,
linkNodeToCategory: () => EMPTY,
unlinkNodeFromCategory: () => EMPTY
}
}
]
});
fixture = TestBed.createComponent(ContentMetadataComponent);
component = fixture.componentInstance;
contentMetadataService = TestBed.inject(ContentMetadataService);
@@ -221,7 +227,7 @@ describe('ContentMetadataComponent', () => {
}));
it('should save changedProperties on save click', fakeAsync(async () => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
spyOn(nodesApiService, 'updateNode').and.returnValue(of(expectedNode));
@@ -231,15 +237,15 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
await fixture.whenStable();
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
await fixture.whenStable();
expect(component.node).toEqual(expectedNode);
expect(nodesApiService.updateNode).toHaveBeenCalled();
}));
it('should call removeTag and assignTagsToNode on TagService on save click', fakeAsync( () => {
component.editable = true;
it('should call removeTag and assignTagsToNode on TagService on save click', () => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
@@ -253,11 +259,11 @@ describe('ContentMetadataComponent', () => {
const tagName2 = 'New tag 3';
updateService.update(property, 'updated-value');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
const tag1 = new TagBody();
tag1.tag = tagName1;
@@ -265,10 +271,10 @@ describe('ContentMetadataComponent', () => {
tag2.tag = tagName2;
expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id);
expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]);
}));
});
it('should call getTagsByNodeId on TagService on save click', fakeAsync( () => {
component.editable = true;
it('should call getTagsByNodeId on TagService on save click', () => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
const expectedNode = { ...node, name: 'some-modified-value' };
@@ -280,17 +286,17 @@ describe('ContentMetadataComponent', () => {
spyOn(tagService, 'assignTagsToNode').and.returnValue(of({}));
updateService.update(property, 'updated-value');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagPaging.list.entries[0].entry.tag, 'New tag 3']);
getTagsByNodeIdSpy.calls.reset();
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
expect(tagService.getTagsByNodeId).toHaveBeenCalledWith(node.id);
}));
});
it('should throw error on unsuccessful save', fakeAsync((done) => {
it('should throw error on unsuccessful save', fakeAsync(() => {
const logService: LogService = TestBed.inject(LogService);
component.editable = true;
const property = { key: 'properties.property-key', value: 'original-value' } as CardViewBaseItemModel;
@@ -302,17 +308,18 @@ describe('ContentMetadataComponent', () => {
expect(err.statusCode).toBe(0);
expect(err.message).toBe('METADATA.ERRORS.GENERIC');
sub.unsubscribe();
done();
});
spyOn(nodesApiService, 'updateNode').and.returnValue(throwError(new Error('My bad')));
fixture.detectChanges();
fixture.whenStable().then(() => clickOnSave());
discardPeriodicTasks();
flush();
}));
it('should open the confirm dialog when content type is changed', fakeAsync(() => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
spyOn(contentMetadataService, 'openConfirmDialog').and.returnValue(of(true));
@@ -323,16 +330,17 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
tick(100);
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
tick(100);
expect(component.node).toEqual(expectedNode);
expect(contentMetadataService.openConfirmDialog).toHaveBeenCalledWith({nodeType: 'ft:poppoli'});
expect(nodesApiService.updateNode).toHaveBeenCalled();
discardPeriodicTasks();
}));
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed', fakeAsync(() => {
component.editable = true;
it('should call removeTag and assignTagsToNode on TagService after confirming confirmation dialog when content type is changed',() => {
component.editableTags = true;
component.displayTags = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = { ...node, nodeType: 'ft:sbiruli' };
@@ -347,25 +355,23 @@ describe('ContentMetadataComponent', () => {
const tagName2 = 'New tag 3';
updateService.update(property, 'ft:poppoli');
tick(600);
fixture.detectChanges();
findTagsCreator().tagsChange.emit([tagName1, tagName2]);
tick(100);
fixture.detectChanges();
clickOnSave();
const mockEvent = new Event('click');
component.saveTagsChanges(mockEvent);
tick(100);
const tag1 = new TagBody();
tag1.tag = tagName1;
const tag2 = new TagBody();
tag2.tag = tagName2;
expect(tagService.removeTag).toHaveBeenCalledWith(node.id, tagPaging.list.entries[1].entry.id);
expect(tagService.assignTagsToNode).toHaveBeenCalledWith(node.id, [tag1, tag2]);
}));
});
it('should retrigger the load of the properties when the content type has changed', fakeAsync(() => {
component.editable = true;
component.editableGeneralInfo = true;
const property = { key: 'nodeType', value: 'ft:sbiruli' } as CardViewBaseItemModel;
const expectedNode = Object.assign({}, node, { nodeType: 'ft:sbiruli' });
spyOn(contentMetadataService, 'openConfirmDialog').and.returnValue(of(true));
@@ -377,14 +383,137 @@ describe('ContentMetadataComponent', () => {
fixture.detectChanges();
tick(100);
clickOnSave();
const mockEvent = new Event('click');
component.saveGeneralInfoChanges(mockEvent);
tick(100);
expect(component.node).toEqual(expectedNode);
expect(updateService.updateNodeAspect).toHaveBeenCalledWith(expectedNode);
}));
it('should save general info changes and toggle editableGeneralInfo', () => {
const event = new Event('click');
spyOn(component, 'saveChanges');
component.editableGeneralInfo = true;
component.saveGeneralInfoChanges(event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(component.editableGeneralInfo).toBe(false);
});
it('should save group changes and set group editable to false', () => {
const group = { editable: true };
const event = new Event('click');
spyOn(component, 'saveChanges');
component.saveGroupChanges(group, event);
expect(component.saveChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
});
describe('cancelChanges', () => {
it('should cancel group changes and set group editable to false', () => {
const group = { editable: true };
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.cancelGroupChanges(group, event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(group.editable).toBe(false);
});
it('should cancel general info changes and toggle editableGeneralInfo', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableGeneralInfo = true;
component.cancelGeneralInfoChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableGeneralInfo).toBe(false);
});
it('should cancel tags changes and toggle editableTags', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableTags = true;
component.CancelTagsChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableTags).toBe(false);
});
it('should cancel categories changes and toggle editableCategories', () => {
const event = new Event('click');
spyOn(component, 'cancelChanges');
component.editableCategories = true;
component.cancelCategoriesChanges(event);
expect(component.cancelChanges).toHaveBeenCalledWith(event);
expect(component.editableCategories).toBe(false);
});
})
describe('editing', () => {
it('should toggle categories edit and set categoriesPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.editableCategories = false;
component.categoriesPanelState = false;
component.toggleCategoriesEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableCategories).toBe(true);
expect(component.categoriesPanelState).toBe(true);
component.toggleCategoriesEdit(event);
expect(component.editableCategories).toBe(false);
expect(component.categoriesPanelState).toBe(false);
});
it('should toggle group edit and expand the panel if editable', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
const group = { editable: false };
component.expandePanel = jasmine.createSpy();
component.toggleEdit(group, event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(group.editable).toBe(true);
expect(component.expandePanel).toHaveBeenCalledWith(group);
});
it('should toggle group edit but not expand the panel if not editable', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
const group = { editable: true };
component.expandePanel = jasmine.createSpy();
component.toggleEdit(group, event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(group.editable).toBe(false);
expect(component.expandePanel).not.toHaveBeenCalled();
});
it('should toggle general info edit and set generalInfoPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.generalInfoPanelState = true;
component.editableGeneralInfo = false;
component.toggleGeneralEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableGeneralInfo).toBe(true);
expect(component.generalInfoPanelState).toBe(true);
component.toggleGeneralEdit(event);
expect(component.editableGeneralInfo).toBe(false);
expect(component.generalInfoPanelState).toBe(true);
});
it('should toggle tags edit and set tagsPanelState accordingly', () => {
const event = new Event('click');
spyOn(event, 'stopPropagation');
component.editableTags = false;
component.tagsPanelState = false;
component.toggleTagsEdit(event);
expect(event.stopPropagation).toHaveBeenCalled();
expect(component.editableTags).toBe(true);
expect(component.tagsPanelState).toBe(true);
component.toggleTagsEdit(event);
expect(component.editableTags).toBe(false);
expect(component.tagsPanelState).toBe(false);
});
})
describe('Reseting', () => {
it('should reset changedProperties on reset click', async () => {
component.changedProperties = { properties: { 'property-key': 'updated-value' } };
@@ -1241,6 +1370,8 @@ describe('ContentMetadataComponent', () => {
expect(categories[0].textContent).toBe(category1.name);
expect(categories[1].textContent).toBe(category2.name);
expect(categoryService.getCategoryLinksForNode).toHaveBeenCalledWith(node.id);
discardPeriodicTasks();
flush();
}));
it('should be hidden when editable is true', () => {
@@ -1333,6 +1464,8 @@ describe('ContentMetadataComponent', () => {
clickOnSave();
expect(categoriesManagementComponent.disableRemoval).toBeFalse();
discardPeriodicTasks();
flush();
}));
it('should set categoryNameControlVisible to false after saving', () => {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { Category, CategoryEntry, CategoryLinkBody, CategoryPaging, Node, TagBody, TagEntry, TagPaging } from '@alfresco/js-api';
import { Observable, Subject, of, zip, forkJoin } from 'rxjs';
import {
@@ -35,6 +35,7 @@ import { TagsCreatorMode } from '../../../tag/tags-creator/tags-creator-mode';
import { TagService } from '../../../tag/services/tag.service';
import { CategoryService } from '../../../category/services/category.service';
import { CategoriesManagementMode } from '../../../category/categories-management/categories-management-mode';
import { MatExpansionPanel } from '@angular/material/expansion';
const DEFAULT_SEPARATOR = ', ';
@@ -46,6 +47,7 @@ const DEFAULT_SEPARATOR = ', ';
encapsulation: ViewEncapsulation.None
})
export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
@ViewChild(MatExpansionPanel) panel: MatExpansionPanel;
protected onDestroy$ = new Subject<boolean>();
/** (required) The node entity to fetch metadata about */
@@ -126,6 +128,13 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
categoriesManagementMode = CategoriesManagementMode.ASSIGN;
categoryControlVisible = false;
classifiableChanged = this.classifiableChangedSubject.asObservable();
generalInfoPanelState: boolean;
editableGeneralInfo: boolean;
tagsPanelState: boolean;
editableTags: boolean = false;
categoriesPanelState: boolean;
editableCategories: boolean = false;
aspectPanelstate: boolean = false;
constructor(
private contentMetadataService: ContentMetadataService,
@@ -229,10 +238,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
* Called after clicking save button. It confirms all changes done for metadata and hides both category and tag name controls.
* Before clicking on that button they are not saved.
*/
saveChanges() {
saveChanges(event: Event) {
event.stopPropagation();
this._saving = true;
this.tagNameControlVisible = false;
this.categoryControlVisible = false;
if (this.hasContentTypeChanged(this.changedProperties)) {
this.contentMetadataService.openConfirmDialog(this.changedProperties).subscribe(() => {
this.updateNode();
@@ -242,6 +251,29 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
}
saveGroupChanges(group: any, event: Event) {
this.saveChanges(event);
group.editable = !group.editable;
}
saveGeneralInfoChanges(event: Event) {
this.saveChanges(event);
this.editableGeneralInfo = !this.editableGeneralInfo;
}
saveTagsChanges(event: Event) {
this.saveChanges(event);
this.tagNameControlVisible = false;
this.editableTags = !this.editableTags;
}
saveCategoriesChanges(event: Event) {
this.saveChanges(event);
this.categoryControlVisible = false;
this.editableCategories = !this.editableCategories;
}
/**
* Register all tags which should be assigned to node. Please note that they are just in "register" state and are not yet saved
* until button for saving data is clicked. Calling that function causes that save button is enabled.
@@ -269,11 +301,32 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
this.hasMetadataChanged = false;
}
cancelChanges() {
cancelChanges(event: Event) {
event.stopPropagation();
this.revertChanges();
this.loadProperties(this.node);
}
cancelGroupChanges(group: any, event: Event) {
this.cancelChanges(event);
group.editable = !group.editable;
}
cancelGeneralInfoChanges(event: Event) {
this.cancelChanges(event);
this.editableGeneralInfo = !this.editableGeneralInfo;
}
CancelTagsChanges(event: Event) {
this.cancelChanges(event);
this.editableTags = !this.editableTags;
}
cancelCategoriesChanges(event: Event) {
this.cancelChanges(event);
this.editableCategories = !this.editableCategories;
}
showGroup(group: CardViewGroup): boolean {
const properties = group.properties.filter((property) => !this.isEmpty(property.displayValue));
@@ -284,10 +337,6 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
return group.title === this.displayAspect;
}
canExpandProperties(): boolean {
return !this.expanded || this.displayAspect === 'Properties';
}
keyDown(event: KeyboardEvent) {
if (event.keyCode === 37 || event.keyCode === 39) { // ArrowLeft && ArrowRight
event.stopPropagation();
@@ -420,4 +469,51 @@ export class ContentMetadataComponent implements OnChanges, OnInit, OnDestroy {
}
return observables;
}
toggleGeneralEdit(event: Event): void {
event.stopPropagation();
this.editableGeneralInfo = !this.editableGeneralInfo;
if (!this.panel.expanded) {
this.panel.open();
}
}
toggleTagsEdit(event: Event): void {
event.stopPropagation();
this.editableTags = !this.editableTags;
if (this.editableTags) {
this.tagsPanelState = true;
} else {
this.tagsPanelState = false;
}
}
toggleCategoriesEdit(event: Event): void {
event.stopPropagation();
this.editableCategories = !this.editableCategories;
if (this.editableCategories) {
this.categoriesPanelState = true;
} else {
this.categoriesPanelState = false;
}
}
toggleEdit(group: any, event: Event): void {
event.stopPropagation();
group.editable = !group.editable;
if(group.editable) {
this.expandePanel(group);
}
}
expandePanel(group: any) {
group.expanded = true;
}
onPanelOpened(group: any): void {
group.aspectPanelstate = true;
}
onPanelClosed(group: any): void {
group.aspectPanelstate = false;
}
}
@@ -25,6 +25,7 @@ export const mockGroupProperties = [
key: 'properties.exif:pixelXDimension',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -40,6 +41,7 @@ export const mockGroupProperties = [
key: 'properties.exif:pixelYDimension',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -49,7 +51,9 @@ export const mockGroupProperties = [
clickCallBack: null,
displayValue: 400
}
]
],
editable: true,
expanded: true,
},
{
title: 'CUSTOM',
@@ -60,6 +64,7 @@ export const mockGroupProperties = [
key: 'properties.custom:abc',
default: null,
editable: true,
editableTags: true,
clickable: false,
icon: '',
data: null,
@@ -69,6 +74,8 @@ export const mockGroupProperties = [
clickCallBack: null,
displayValue: 400
}
]
],
editable: true,
expanded: true,
}
];

Some files were not shown because too many files have changed in this diff Show More