diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 1c4ac1f..b5b427a 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -21,8 +21,17 @@ jobs: - name: Lint check run: npm run lint:check - - name: Licence checker + - name: Install dependencies run: | cd client npm ci + # Install sheet + wget ${{ secrets.SHEETLINK }} + mv ${{ secrets.SHEETNAME }} ${{ secrets.SHEETNAME }}.tgz + npm i ${{ secrets.SHEETNAME }}.tgz + # End + + - name: Licence checker + run: | + cd client npm run license-checker \ No newline at end of file diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index 9b92175..343f363 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -34,7 +34,14 @@ jobs: CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }} - name: Install dependencies - run: npm ci + run: | + npm ci + cd client + # Install sheet + wget ${{ secrets.SHEETLINK }} + mv ${{ secrets.SHEETNAME }} ${{ secrets.SHEETNAME }}.tgz + npm i ${{ secrets.SHEETNAME }}.tgz + # End - name: Check audit # Audit should fail and stop the CI if critical vulnerability found @@ -86,7 +93,14 @@ jobs: CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }} - name: Install dependencies - run: npm ci + run: | + npm ci + cd client + # Install sheet + wget ${{ secrets.SHEETLINK }} + mv ${{ secrets.SHEETNAME }} ${{ secrets.SHEETNAME }}.tgz + npm i ${{ secrets.SHEETNAME }}.tgz + # End # Install pm2 and prepare SASJS server - run: npm i -g pm2 @@ -185,6 +199,11 @@ jobs: run: | cd client npm ci + # Install sheet + wget ${{ secrets.SHEETLINK }} + mv ${{ secrets.SHEETNAME }} ${{ secrets.SHEETNAME }}.tgz + npm i ${{ secrets.SHEETNAME }}.tgz + # End npm run build - name: Build SAS9 EBI Release diff --git a/CHANGELOG.md b/CHANGELOG.md index e865e5b..336cc05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [6.6.4](https://git.datacontroller.io/dc/dc/compare/v6.6.3...v6.6.4) (2024-04-01) + + +### Bug Fixes + +* ordering SOFTSELECT numerically in dropdown ([f522038](https://git.datacontroller.io/dc/dc/commit/f522038b8ddb1da14b8adbf8346d0a4539a94cc8)), closes [#85](https://git.datacontroller.io/dc/dc/issues/85) +* reverting col ([fbbcf90](https://git.datacontroller.io/dc/dc/commit/fbbcf90956bf538b032b0107c07b8576d20353b9)) +* typo ([31d4e5c](https://git.datacontroller.io/dc/dc/commit/31d4e5c727f790d428fb2ea8da60dca929561805)) + ## [6.6.3](https://git.datacontroller.io/dc/dc/compare/v6.6.2...v6.6.3) (2024-02-26) diff --git a/client/package-lock.json b/client/package-lock.json index b243de8..36dd91e 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -23,7 +23,7 @@ "@handsontable/angular": "^13.1.0", "@sasjs/adapter": "4.10.2", "@sasjs/utils": "^3.4.0", - "@sheet/crypto": "1.20211122.1", + "@sheet/crypto": "file:../../../RESOURCES/libs/0fae52415ec93a6dd3d5bd33c73b6dc124a07496be568a7aba6d033ec65df60b.tgz", "@types/d3-graphviz": "^2.6.7", "@types/text-encoding": "0.0.35", "base64-arraybuffer": "^0.2.0", @@ -4652,7 +4652,7 @@ }, "node_modules/@sheet/crypto": { "version": "1.20211122.1", - "resolved": "https://pylon.sheetjs.com:54111/@sheet%2fcrypto/-/crypto-1.20211122.1.tgz", + "resolved": "file:../../../RESOURCES/libs/0fae52415ec93a6dd3d5bd33c73b6dc124a07496be568a7aba6d033ec65df60b.tgz", "integrity": "sha512-G3/HWyzFUYbbVQoQIa+KSeMOhFnK492Ep595FXbzWN9IGZSwuvFl4saEyMl8R8pE2Al5YgSZuR9MpDpx3f7Izg==", "bin": { "xlsx": "bin/xlsx.njs" @@ -23681,8 +23681,7 @@ } }, "@sheet/crypto": { - "version": "1.20211122.1", - "resolved": "https://pylon.sheetjs.com:54111/@sheet%2fcrypto/-/crypto-1.20211122.1.tgz", + "version": "file:../../../RESOURCES/libs/0fae52415ec93a6dd3d5bd33c73b6dc124a07496be568a7aba6d033ec65df60b.tgz", "integrity": "sha512-G3/HWyzFUYbbVQoQIa+KSeMOhFnK492Ep595FXbzWN9IGZSwuvFl4saEyMl8R8pE2Al5YgSZuR9MpDpx3f7Izg==" }, "@sideway/address": { diff --git a/client/package.json b/client/package.json index 4b57efe..507f69c 100644 --- a/client/package.json +++ b/client/package.json @@ -51,7 +51,6 @@ "@handsontable/angular": "^13.1.0", "@sasjs/adapter": "4.10.2", "@sasjs/utils": "^3.4.0", - "@sheet/crypto": "1.20211122.1", "@types/d3-graphviz": "^2.6.7", "@types/text-encoding": "0.0.35", "base64-arraybuffer": "^0.2.0", diff --git a/client/src/app/editor/components/edit-record/edit-record.component.html b/client/src/app/editor/components/edit-record/edit-record.component.html index c678fcf..73c5f84 100644 --- a/client/src/app/editor/components/edit-record/edit-record.component.html +++ b/client/src/app/editor/components/edit-record/edit-record.component.html @@ -112,7 +112,7 @@
0) { hot.setCellMeta(entry.row, entry.col, 'renderer', 'autocomplete') - hot.setCellMeta(entry.row, entry.col, 'editor', 'autocomplete') + hot.setCellMeta(entry.row, entry.col, 'editor', 'autocomplete.custom') hot.setCellMeta(entry.row, entry.col, 'strict', entry.strict) hot.setCellMeta(entry.row, entry.col, 'filter', false) this.currentEditRecordValidator?.updateRule(entry.col, { renderer: 'autocomplete', - editor: 'autocomplete', + editor: 'autocomplete.custom', strict: entry.strict, filter: false }) @@ -2059,13 +2059,13 @@ export class EditorComponent implements OnInit, AfterViewInit { } hot.setCellMeta(row, cellCol, 'renderer', 'autocomplete') - hot.setCellMeta(row, cellCol, 'editor', 'autocomplete') + hot.setCellMeta(row, cellCol, 'editor', 'autocomplete.custom') hot.setCellMeta(row, cellCol, 'strict', cellValidationEntry.strict) hot.setCellMeta(row, cellCol, 'filter', false) this.currentEditRecordValidator?.updateRule(cellCol, { renderer: 'autocomplete', - editor: 'autocomplete', + editor: 'autocomplete.custom', strict: cellValidationEntry.strict, filter: false }) @@ -2708,13 +2708,13 @@ export class EditorComponent implements OnInit, AfterViewInit { const strict = this.cellValidationSource[validationSourceIndex].strict hot.setCellMeta(row, column, 'renderer', 'autocomplete') - hot.setCellMeta(row, column, 'editor', 'autocomplete') + hot.setCellMeta(row, column, 'editor', 'autocomplete.custom') hot.setCellMeta(row, column, 'strict', strict) hot.setCellMeta(row, column, 'filter', false) this.currentEditRecordValidator?.updateRule(column, { renderer: 'autocomplete', - editor: 'autocomplete', + editor: 'autocomplete.custom', strict: strict, filter: false }) @@ -2958,6 +2958,37 @@ export class EditorComponent implements OnInit, AfterViewInit { ) } + /** + * Function checks if selected hot cell is solo cell selected + * and if it is, set the `filter` property based on filter param. + * + * @param filter + */ + private setCellFilter(filter: boolean) { + const hotSelected = this.hotInstance.getSelected() + const selection = hotSelected ? hotSelected[0] : hotSelected + + // When we open a dropdown we want filter disabled so value in cell + // don't filter out items, since we want to see them all. + // But when we start typing we want to be able to start filtering values + // again + if (selection) { + const startRow = selection[0] + const endRow = selection[2] + const startCell = selection[1] + const endCell = selection[3] + + if (startRow === endRow && startCell === endCell) { + const cellMeta = this.hotInstance.getCellMeta(startRow, startCell) + + // If filter is not already set at the value in the param, set it + if (cellMeta && cellMeta.filter === !filter) { + this.hotInstance.setCellMeta(startRow, startCell, 'filter', filter) + } + } + } + } + async ngOnInit() { this.licenceService.hot_license_key.subscribe( (hot_license_key: string | undefined) => { @@ -3314,28 +3345,16 @@ export class EditorComponent implements OnInit, AfterViewInit { } ) - hot.addHook('beforeKeyDown', (e: any) => { - const hotSelected = this.hotInstance.getSelected() - const selection = hotSelected ? hotSelected[0] : hotSelected - + hot.addHook('afterBeginEditing', () => { // When we open a dropdown we want filter disabled so value in cell // don't filter out items, since we want to see them all. + this.setCellFilter(false) + }) + + hot.addHook('beforeKeyDown', () => { // When we start typing, we are enabling the filter since we want to find // values faster. - if (selection) { - const startRow = selection[0] - const endRow = selection[2] - const startCell = selection[1] - const endCell = selection[3] - - if (startRow === endRow && startCell === endCell) { - const cellMeta = this.hotInstance.getCellMeta(startRow, startCell) - - if (cellMeta && cellMeta.filter === false) { - this.hotInstance.setCellMeta(startRow, startCell, 'filter', true) - } - } - } + this.setCellFilter(true) }) hot.addHook('afterChange', (source: any, change: any) => { diff --git a/client/src/app/shared/dc-validator/dc-validator.ts b/client/src/app/shared/dc-validator/dc-validator.ts index 75bc25e..b87f541 100644 --- a/client/src/app/shared/dc-validator/dc-validator.ts +++ b/client/src/app/shared/dc-validator/dc-validator.ts @@ -20,6 +20,7 @@ import { parseColType } from './utils/parseColType' import { dqValidate } from './validations/dq-validation' import { specialMissingNumericValidator } from './validations/hot-custom-validators' import { applyNumericFormats } from './utils/applyNumericFormats' +import { CustomAutocompleteEditor } from './editors/numericAutocomplete' export class DcValidator { private rules: DcValidation[] = [] @@ -38,6 +39,8 @@ export class DcValidator { dqData: DQData[], hotInstance?: Handsontable ) { + this.registerCustomEditors() + this.sasparams = sasparams this.hotInstance = hotInstance this.rules = parseColType(sasparams.COLTYPE) @@ -51,6 +54,13 @@ export class DcValidator { this.setupValidations() } + registerCustomEditors() { + Handsontable.editors.registerEditor( + 'autocomplete.custom', + CustomAutocompleteEditor + ) + } + getRules(): DcValidation[] { return this.rules } @@ -262,6 +272,7 @@ export class DcValidator { if (source.length > 0) { this.rules[i].source = source this.rules[i].type = 'autocomplete' + this.rules[i].editor = 'autocomplete.custom' this.rules[i].filter = false } @@ -315,7 +326,10 @@ export class DcValidator { // Because of dynamic cell validation, that will change the type of cell to dropdown // `rules[i].colType` could be different type (eg. numeric). So we check if current cell is dropdown, to call HOT native dropdown validator - if (this.editor === 'autocomplete') { + if ( + this.editor === 'autocomplete' || + this.editor === 'autocomplete.custom' + ) { self .getHandsontableValidator('autocomplete') .call(this, value, (valid: boolean) => { diff --git a/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts b/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts new file mode 100644 index 0000000..20b11df --- /dev/null +++ b/client/src/app/shared/dc-validator/editors/numericAutocomplete.ts @@ -0,0 +1,28 @@ +import Handsontable from 'handsontable' +import Core from 'handsontable/core' + +export class CustomAutocompleteEditor extends Handsontable.editors + .AutocompleteEditor { + constructor(instance: Core) { + super(instance) + } + + createElements() { + super.createElements() + } + + // Listbox open + open(event?: Event | undefined): void { + super.open(event) + + if (this.isCellNumeric()) { + this.htContainer.classList.add('numericListbox') + } else { + this.htContainer.classList.remove('numericListbox') + } + } + + isCellNumeric() { + return this.cellProperties?.className?.includes('htNumeric') + } +} diff --git a/client/src/styles.scss b/client/src/styles.scss index ef72978..396e38c 100644 --- a/client/src/styles.scss +++ b/client/src/styles.scss @@ -713,6 +713,11 @@ clr-icon.is-info { border: 1px solid red !important; color: #ffffff !important; } + +.handsontable .numericListbox { + text-align: right; +} + .margin-top-20 { margin-top: 20px; } diff --git a/package.json b/package.json index 149fd3f..1de4d96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dcfrontend", - "version": "6.6.3", + "version": "6.6.4", "description": "Data Controller", "devDependencies": { "@saithodev/semantic-release-gitea": "^2.1.0",