diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index fee7c9c24..9c5f6d31a 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -49,7 +49,7 @@
"patch-db-client": "file: ../../../patch-db/client",
"pbkdf2": "^3.1.2",
"rxjs": "^7.5.6",
- "start-sdk": "^0.4.0-lib0.alpha8",
+ "start-sdk": "^0.4.0-lib0.alpha9",
"swiper": "^8.2.4",
"ts-matches": "^5.2.1",
"tslib": "^2.3.0",
@@ -13771,9 +13771,9 @@
}
},
"node_modules/start-sdk": {
- "version": "0.4.0-lib0.alpha8",
- "resolved": "https://registry.npmjs.org/start-sdk/-/start-sdk-0.4.0-lib0.alpha8.tgz",
- "integrity": "sha512-qErlv8ikV8nYqyCxxSN856dUwddGK5OOwTXk62IiJPxY3si03P1NQ3MnFch6Vx3NXiOmKeNNqw4/bj26TdUWRA==",
+ "version": "0.4.0-lib0.alpha9",
+ "resolved": "https://registry.npmjs.org/start-sdk/-/start-sdk-0.4.0-lib0.alpha9.tgz",
+ "integrity": "sha512-F+ekxjVEKgNv7SU5XCe1rn7PqbKsbqCSS7pecMxcKQmbNlic4iyo3+lIS9JuPBSyTTjJlzJFzkdaxGwf4h83mg==",
"dependencies": {
"@iarna/toml": "^2.2.5",
"lodash": "^4.17.21",
diff --git a/frontend/package.json b/frontend/package.json
index dfc0c517a..033fd2b9f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -74,7 +74,7 @@
"patch-db-client": "file: ../../../patch-db/client",
"pbkdf2": "^3.1.2",
"rxjs": "^7.5.6",
- "start-sdk": "^0.4.0-lib0.alpha8",
+ "start-sdk": "^0.4.0-lib0.alpha9",
"swiper": "^8.2.4",
"ts-matches": "^5.2.1",
"tslib": "^2.3.0",
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object.module.ts b/frontend/projects/ui/src/app/components/form-object/form-object.module.ts
index d1ad3acee..9741114ec 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object.module.ts
+++ b/frontend/projects/ui/src/app/components/form-object/form-object.module.ts
@@ -5,7 +5,6 @@ import { IonicModule } from '@ionic/angular'
import { SharedPipesModule } from '@start9labs/shared'
import { TuiElasticContainerModule } from '@taiga-ui/kit'
import { TuiExpandModule } from '@taiga-ui/core'
-import { EnumListPageModule } from 'src/app/modals/enum-list/enum-list.module'
import { FormLabelComponent } from './form-label/form-label.component'
import { FormObjectComponent } from './form-object/form-object.component'
import { FormUnionComponent } from './form-union/form-union.component'
@@ -13,15 +12,13 @@ import {
GetErrorPipe,
ToWarningTextPipe,
ToElementIdPipe,
- ToEnumListDisplayPipe,
ToRangePipe,
} from './form-object.pipes'
import { FormFileComponent } from './form-object/controls/form-file/form-file.component'
import { FormInputComponent } from './form-object/controls/form-input/form-input.component'
import { FormWarningDirective } from './form-warning.directive'
import { FormSubformComponent } from './form-object/controls/form-subform/form-subform.component'
-import { FormEnumComponent } from './form-object/controls/form-enum/form-enum.component'
-import { FormValueComponent } from './form-object/controls/form-value/form-value.component'
+import { FormSelectComponent } from './form-object/controls/form-select/form-select.component'
@NgModule({
declarations: [
@@ -30,15 +27,13 @@ import { FormValueComponent } from './form-object/controls/form-value/form-value
FormLabelComponent,
ToWarningTextPipe,
GetErrorPipe,
- ToEnumListDisplayPipe,
ToElementIdPipe,
ToRangePipe,
FormWarningDirective,
FormFileComponent,
FormInputComponent,
FormSubformComponent,
- FormEnumComponent,
- FormValueComponent,
+ FormSelectComponent,
],
imports: [
CommonModule,
@@ -46,7 +41,6 @@ import { FormValueComponent } from './form-object/controls/form-value/form-value
FormsModule,
ReactiveFormsModule,
SharedPipesModule,
- EnumListPageModule,
TuiElasticContainerModule,
TuiExpandModule,
],
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object.pipes.ts b/frontend/projects/ui/src/app/components/form-object/form-object.pipes.ts
index e4f3e967d..6faae4ce3 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object.pipes.ts
+++ b/frontend/projects/ui/src/app/components/form-object/form-object.pipes.ts
@@ -1,12 +1,6 @@
import { Pipe, PipeTransform } from '@angular/core'
-import {
- AbstractControl,
- FormGroup,
- UntypedFormArray,
- ValidationErrors,
-} from '@angular/forms'
+import { ValidationErrors } from '@angular/forms'
import { IonicSafeString } from '@ionic/angular'
-import { ListValueSpecOf } from 'start-sdk/types/config-types'
import { Range } from 'src/app/util/config-utilities'
import { getElementId } from './form-object/form-object.component'
@@ -40,15 +34,6 @@ export class GetErrorPipe implements PipeTransform {
}
}
-@Pipe({
- name: 'toEnumListDisplay',
-})
-export class ToEnumListDisplayPipe implements PipeTransform {
- transform(arr: string[], spec: ListValueSpecOf<'enum'>): string {
- return arr.map((v: string) => spec['value-names'][v]).join(', ')
- }
-}
-
@Pipe({
name: 'toWarningText',
})
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.html b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.html
deleted file mode 100644
index 9aa3116d6..000000000
--- a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- {{ control.value | toEnumListDisplay : $any(spec.spec) }}
-
-
-
-
-
-
-
- {{ errors | getError }}
-
-
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.ts b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.ts
deleted file mode 100644
index d3829b6c5..000000000
--- a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, Input, Output, EventEmitter } from '@angular/core'
-import { AbstractControl } from '@angular/forms'
-import { ValueSpecOf } from 'start-sdk/types/config-types'
-
-@Component({
- selector: 'form-enum',
- templateUrl: './form-enum.component.html',
- styleUrls: ['./form-enum.component.scss'],
-})
-export class FormEnumComponent {
- @Input() spec!: ValueSpecOf<'list'>
- @Input() control!: AbstractControl
-
- @Output() edit = new EventEmitter()
-}
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.html b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.html
similarity index 55%
rename from frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.html
rename to frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.html
index fe954ca58..8beb43015 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.html
+++ b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.html
@@ -13,12 +13,12 @@
#warning="formWarning"
slot="end"
[formControl]="control"
- (ionChange)="warning.onChange(name, spec, undefined, cancel)"
+ (ionChange)="warning.onChange(name, spec, undefined, cancelBool)"
>
-
-
+
+
1
+ ? '[' + control.value.length + ' selected]'
+ : spec['value-names'][control.value]
+ "
>
{{ spec['value-names'][option] }}
+
+
+ {{ errors | getError }}
+
+
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.scss b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.scss
similarity index 57%
rename from frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.scss
rename to frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.scss
index 15611686c..f03aa603a 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-enum/form-enum.component.scss
+++ b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.scss
@@ -1,11 +1,3 @@
-.label {
- margin: 16px 0 6px;
-}
-
-.list {
- white-space: nowrap;
-}
-
.error-message {
margin-top: 2px;
font-size: small;
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.ts b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.ts
new file mode 100644
index 000000000..ec49cf9bc
--- /dev/null
+++ b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-select/form-select.component.ts
@@ -0,0 +1,16 @@
+import { Component, Input } from '@angular/core'
+import { FormControl } from '@angular/forms'
+import { ValueSpecOf } from 'start-sdk/types/config-types'
+
+@Component({
+ selector: 'form-select',
+ templateUrl: './form-select.component.html',
+ styleUrls: ['./form-select.component.scss'],
+})
+export class FormSelectComponent {
+ @Input() spec!: ValueSpecOf<'boolean' | 'select' | 'multiselect'>
+ @Input() control!: FormControl
+ @Input() name!: string
+
+ cancelBool = () => this.control.setValue(!this.control.value)
+}
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.ts b/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.ts
deleted file mode 100644
index 66b99181a..000000000
--- a/frontend/projects/ui/src/app/components/form-object/form-object/controls/form-value/form-value.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, Input } from '@angular/core'
-import { FormControl } from '@angular/forms'
-import { ValueSpecOf } from 'start-sdk/types/config-types'
-
-@Component({
- selector: 'form-value',
- templateUrl: './form-value.component.html',
-})
-export class FormValueComponent {
- @Input() spec!: ValueSpecOf<'boolean' | 'enum'>
- @Input() control!: FormControl
- @Input() name!: string
-
- cancel = () => this.control.setValue(!this.control.value)
-}
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.html b/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.html
index 3c5b626a2..a9f77fcbe 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.html
+++ b/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.html
@@ -15,13 +15,17 @@
[control]="$any(entry.value)"
(onInputChange)="handleInputChange()"
>
-
-
+
+ >
-
-
+
+
-
-
diff --git a/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.ts b/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.ts
index e5ed4e402..abba90aa8 100644
--- a/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.ts
+++ b/frontend/projects/ui/src/app/components/form-object/form-object/form-object.component.ts
@@ -7,7 +7,7 @@ import {
inject,
SimpleChanges,
} from '@angular/core'
-import { FormArray, UntypedFormArray, UntypedFormGroup } from '@angular/forms'
+import { UntypedFormArray, UntypedFormGroup } from '@angular/forms'
import { AlertButton, AlertController, ModalController } from '@ionic/angular'
import {
InputSpec,
@@ -15,11 +15,9 @@ import {
ValueSpec,
ValueSpecBoolean,
ValueSpecList,
- ValueSpecListOf,
ValueSpecUnion,
} from 'start-sdk/types/config-types'
import { FormService } from 'src/app/services/form.service'
-import { EnumListPage } from 'src/app/modals/enum-list/enum-list.page'
import { THEME, pauseFor } from '@start9labs/shared'
import { v4 } from 'uuid'
import { DOCUMENT } from '@angular/common'
@@ -148,28 +146,6 @@ export class FormObjectComponent {
}
}
- async presentModalEnumList(
- key: string,
- spec: ValueSpecListOf<'enum'>,
- current: string[],
- ) {
- const modal = await this.modalCtrl.create({
- componentProps: {
- key,
- spec,
- current,
- },
- component: EnumListPage,
- })
-
- modal.onWillDismiss().then(({ data }) => {
- if (!data) return
- this.updateEnumList(key, current, data)
- })
-
- await modal.present()
- }
-
async presentAlertChangeWarning(
key: string,
spec: T extends ValueSpecUnion ? never : T,
@@ -272,27 +248,6 @@ export class FormObjectComponent {
})
}
- private updateEnumList(key: string, current: string[], updated: string[]) {
- const arr = this.formGroup.get(key) as FormArray
-
- for (let i = current.length - 1; i >= 0; i--) {
- if (!updated.includes(current[i])) {
- arr.removeAt(i)
- }
- }
-
- const listSpec = this.objectSpec[key] as ValueSpecList
-
- updated.forEach(val => {
- if (!current.includes(val)) {
- const newItem = this.formService.getListItem(listSpec, val)!
- arr.insert(arr.length, newItem)
- }
- })
-
- arr.markAsDirty()
- }
-
asIsOrder() {
return 0
}
diff --git a/frontend/projects/ui/src/app/modals/enum-list/enum-list.module.ts b/frontend/projects/ui/src/app/modals/enum-list/enum-list.module.ts
deleted file mode 100644
index e48633d31..000000000
--- a/frontend/projects/ui/src/app/modals/enum-list/enum-list.module.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { NgModule } from '@angular/core'
-import { CommonModule } from '@angular/common'
-import { IonicModule } from '@ionic/angular'
-import { EnumListPage } from './enum-list.page'
-import { FormsModule } from '@angular/forms'
-
-@NgModule({
- declarations: [EnumListPage],
- imports: [
- CommonModule,
- IonicModule,
- FormsModule,
- ],
- exports: [EnumListPage],
-})
-export class EnumListPageModule { }
\ No newline at end of file
diff --git a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.html b/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.html
deleted file mode 100644
index 6fb341132..000000000
--- a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
- {{ spec.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ selectAll ? 'Select All' : 'Deselect All' }}
-
-
-
-
- {{ spec.spec['value-names'][option.key] }}
-
-
-
-
-
-
-
-
-
- Done
-
-
-
-
diff --git a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.scss b/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts b/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts
deleted file mode 100644
index be0a7e4f0..000000000
--- a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Component, Input } from '@angular/core'
-import { ModalController } from '@ionic/angular'
-import { ValueSpecListOf } from 'start-sdk/types/config-types'
-
-@Component({
- selector: 'enum-list',
- templateUrl: './enum-list.page.html',
- styleUrls: ['./enum-list.page.scss'],
-})
-export class EnumListPage {
- @Input() key!: string
- @Input() spec!: ValueSpecListOf<'enum'>
- @Input() current: string[] = []
-
- options: { [option: string]: boolean } = {}
- selectAll = false
-
- constructor(private readonly modalCtrl: ModalController) {}
-
- ngOnInit() {
- for (let val of this.spec.spec.values || []) {
- this.options[val] = this.current.includes(val)
- }
- // if none are selected, set selectAll to true
- this.selectAll = Object.values(this.options).some(k => !k)
- }
-
- dismiss() {
- this.modalCtrl.dismiss()
- }
-
- save() {
- this.modalCtrl.dismiss(
- Object.keys(this.options).filter(key => this.options[key]),
- )
- }
-
- toggleSelectAll() {
- Object.keys(this.options).forEach(k => (this.options[k] = this.selectAll))
- this.selectAll = !this.selectAll
- }
-
- toggleSelected(key: string) {
- this.options[key] = !this.options[key]
- }
-
- asIsOrder() {
- return 0
- }
-}
diff --git a/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.page.ts b/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.page.ts
index ab6d3cd0c..1113410f2 100644
--- a/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.page.ts
+++ b/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.page.ts
@@ -253,8 +253,8 @@ const SAMPLE_CONFIG: InputSpec = {
default: true,
warning: null,
},
- 'sample-enum': {
- type: 'enum',
+ 'sample-select': {
+ type: 'multiselect',
name: 'Example Enum Select',
values: ['red', 'blue', 'green'],
'value-names': {
@@ -263,8 +263,9 @@ const SAMPLE_CONFIG: InputSpec = {
green: 'Green',
},
// optional
- warning: 'Example warning to display when changing this enum value.',
- description: 'Example description for enum select',
- default: 'red',
+ warning: 'Example warning to display when changing this select value.',
+ description: 'Example description for select select',
+ range: '[0, 2)',
+ default: ['red'],
},
}
diff --git a/frontend/projects/ui/src/app/pages/developer-routes/developer-menu/form-info.ts b/frontend/projects/ui/src/app/pages/developer-routes/developer-menu/form-info.ts
index fca73a5b3..97bc54804 100644
--- a/frontend/projects/ui/src/app/pages/developer-routes/developer-menu/form-info.ts
+++ b/frontend/projects/ui/src/app/pages/developer-routes/developer-menu/form-info.ts
@@ -110,7 +110,7 @@ export function getBasicInfoSpec(devData: DevProjectData): InputSpec {
warning: null,
},
license: {
- type: 'enum',
+ type: 'select',
name: 'License',
warning: null,
values: [
@@ -135,7 +135,7 @@ export function getBasicInfoSpec(devData: DevProjectData): InputSpec {
'the-unlicense': 'The Unlicense',
custom: 'Custom',
},
- description: 'Example description for enum select',
+ description: 'Example description for select',
default: 'mit',
},
'wrapper-repo': {
diff --git a/frontend/projects/ui/src/app/services/api/api.fixures.ts b/frontend/projects/ui/src/app/services/api/api.fixures.ts
index 9e93cf71b..016ae95b9 100644
--- a/frontend/projects/ui/src/app/services/api/api.fixures.ts
+++ b/frontend/projects/ui/src/app/services/api/api.fixures.ts
@@ -963,7 +963,7 @@ export module Mock {
},
'favorite-flower': {
name: 'Favorite Flower',
- type: 'enum',
+ type: 'select',
description: 'Select your favorite flower',
warning: null,
'value-names': {
@@ -989,19 +989,34 @@ export module Mock {
'unique-by': 'preference',
},
},
- 'random-enum': {
- name: 'Random Enum',
- type: 'enum',
+ 'random-select': {
+ name: 'Random Select',
+ type: 'select',
'value-names': {
- null: 'Null',
- option1: 'One 1',
- option2: 'Two 2',
- option3: 'Three 3',
+ hello: 'Hello',
+ goodbye: 'Goodbye',
+ sup: 'Sup',
},
- default: 'null',
+ default: 'sup',
description: 'This is not even real.',
warning: 'Be careful changing this!',
- values: ['null', 'option1', 'option2', 'option3'],
+ values: ['hello', 'goodbye', 'sup'],
+ },
+ notifications: {
+ name: 'Notification Preferences',
+ type: 'multiselect',
+ description: 'how you want to be notified',
+ warning: null,
+ range: '(1,3]',
+ 'value-names': {
+ email: 'EEEEmail',
+ text: 'Texxxt',
+ call: 'Ccccall',
+ push: 'PuuuusH',
+ webhook: 'WebHooookkeee',
+ },
+ values: ['email', 'text', 'call', 'push', 'webhook'],
+ default: ['email'],
},
'favorite-number': {
name: 'Favorite Number',
@@ -1292,25 +1307,6 @@ export module Mock {
description: 'Advanced settings',
warning: null,
spec: {
- notifications: {
- name: 'Notification Preferences',
- type: 'list',
- subtype: 'enum',
- description: 'how you want to be notified',
- warning: null,
- range: '[1,3]',
- default: ['email'],
- spec: {
- 'value-names': {
- email: 'EEEEmail',
- text: 'Texxxt',
- call: 'Ccccall',
- push: 'PuuuusH',
- webhook: 'WebHooookkeee',
- },
- values: ['email', 'text', 'call', 'push', 'webhook'],
- },
- },
rpcsettings: {
name: 'RPC Settings',
type: 'object',
@@ -1525,7 +1521,7 @@ export module Mock {
},
],
'union-list': undefined,
- 'random-enum': 'option2',
+ 'random-select': ['goodbye'],
'favorite-number': 0,
rpcsettings: {
laws: {
diff --git a/frontend/projects/ui/src/app/services/form.service.ts b/frontend/projects/ui/src/app/services/form.service.ts
index 1cc1fc6cd..6b4b8b39b 100644
--- a/frontend/projects/ui/src/app/services/form.service.ts
+++ b/frontend/projects/ui/src/app/services/form.service.ts
@@ -17,7 +17,8 @@ import {
ListValueSpecUnion,
UniqueBy,
ValueSpec,
- ValueSpecEnum,
+ ValueSpecSelect,
+ ValueSpecMultiselect,
ValueSpecFile,
ValueSpecList,
ValueSpecNumber,
@@ -49,8 +50,8 @@ export class FormService {
const { variants, tag } = spec
const { name, description, warning, 'variant-names': variantNames } = tag
- const enumSpec: ValueSpecEnum = {
- type: 'enum',
+ const enumSpec: ValueSpecSelect = {
+ type: 'select',
name,
description,
warning,
@@ -71,8 +72,6 @@ export class FormService {
return this.formBuilder.control(entry, listItemValidators)
} else if (isValueSpecListOf(spec, 'number')) {
return this.formBuilder.control(entry, listItemValidators)
- } else if (isValueSpecListOf(spec, 'enum')) {
- return this.formBuilder.control(entry)
} else if (isValueSpecListOf(spec, 'object')) {
return this.getFormGroup(spec.spec.spec, listItemValidators, entry)
} else if (isValueSpecListOf(spec, 'union')) {
@@ -99,7 +98,6 @@ export class FormService {
spec: ValueSpec,
currentValue?: any,
): UntypedFormGroup | UntypedFormArray | UntypedFormControl {
- let validators: ValidatorFn[]
let value: any
switch (spec.type) {
case 'string':
@@ -140,9 +138,12 @@ export class FormService {
isValid ? currentValue : undefined,
)
case 'boolean':
- case 'enum':
+ case 'select':
value = currentValue === undefined ? spec.default : currentValue
return this.formBuilder.control(value)
+ case 'multiselect':
+ value = currentValue === undefined ? spec.default : currentValue
+ return this.formBuilder.control(value, multiselectValidators(spec))
default:
return this.formBuilder.control(null)
}
@@ -193,17 +194,16 @@ function numberValidators(
return validators
}
+function multiselectValidators(spec: ValueSpecMultiselect): ValidatorFn[] {
+ const validators: ValidatorFn[] = []
+ validators.push(listInRange(spec.range))
+ return validators
+}
+
function listValidators(spec: ValueSpecList): ValidatorFn[] {
const validators: ValidatorFn[] = []
-
validators.push(listInRange(spec.range))
-
validators.push(listItemIssue())
-
- if (!isValueSpecListOf(spec, 'enum')) {
- validators.push(listUnique(spec))
- }
-
return validators
}
@@ -314,7 +314,6 @@ function listItemEquals(spec: ValueSpecList, val1: any, val2: any): boolean {
switch (spec.subtype) {
case 'string':
case 'number':
- case 'enum':
return val1 == val2
case 'object':
const obj: ListValueSpecObject = spec.spec as any
@@ -334,7 +333,7 @@ function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean {
case 'string':
case 'number':
case 'boolean':
- case 'enum':
+ case 'select':
return val1 == val2
case 'object':
// TODO: 'unique-by' does not exist on ValueSpecObject, fix types
diff --git a/frontend/projects/ui/src/app/util/config-utilities.ts b/frontend/projects/ui/src/app/util/config-utilities.ts
index 6acd67815..207b91ecf 100644
--- a/frontend/projects/ui/src/app/util/config-utilities.ts
+++ b/frontend/projects/ui/src/app/util/config-utilities.ts
@@ -1,4 +1,4 @@
-import { ValueSpec, DefaultString } from 'start-sdk/types/config-types'
+import { DefaultString } from 'start-sdk/types/config-types'
export class Range {
min?: number
@@ -31,95 +31,21 @@ export class Range {
}
}
- hasMin(): this is Range & { min: number } {
+ private hasMin(): this is Range & { min: number } {
return this.min !== undefined
}
- hasMax(): this is Range & { max: number } {
+ private hasMax(): this is Range & { max: number } {
return this.max !== undefined
}
- minMessage(): string {
+ private minMessage(): string {
return `greater than${this.minInclusive ? ' or equal to' : ''} ${this.min}`
}
- maxMessage(): string {
+ private maxMessage(): string {
return `less than${this.maxInclusive ? ' or equal to' : ''} ${this.max}`
}
-
- description(): string {
- let message = 'Value can be any number.'
-
- if (this.hasMin() || this.hasMax()) {
- message = 'Value must be'
- }
-
- if (this.hasMin() && this.hasMax()) {
- message = `${message} ${this.minMessage()} AND ${this.maxMessage()}.`
- } else if (this.hasMin() && !this.hasMax()) {
- message = `${message} ${this.minMessage()}.`
- } else if (!this.hasMin() && this.hasMax()) {
- message = `${message} ${this.maxMessage()}.`
- }
-
- return message
- }
-
- integralMin(): number | undefined {
- if (this.min) {
- const ceil = Math.ceil(this.min)
- if (this.minInclusive) {
- return ceil
- } else {
- if (ceil === this.min) {
- return ceil + 1
- } else {
- return ceil
- }
- }
- }
- }
-
- integralMax(): number | undefined {
- if (this.max) {
- const floor = Math.floor(this.max)
- if (this.maxInclusive) {
- return floor
- } else {
- if (floor === this.max) {
- return floor - 1
- } else {
- return floor
- }
- }
- }
- }
-}
-
-export function getDefaultDescription(spec: ValueSpec): string {
- let toReturn: string | undefined
- switch (spec.type) {
- case 'string':
- if (typeof spec.default === 'string') {
- toReturn = spec.default
- } else if (typeof spec.default === 'object') {
- toReturn = 'random'
- }
- break
- case 'number':
- if (typeof spec.default === 'number') {
- toReturn = String(spec.default)
- }
- break
- case 'boolean':
- toReturn = spec.default === true ? 'True' : 'False'
- break
- case 'enum':
- toReturn = spec['value-names'][spec.default]
- break
- }
-
- return toReturn || ''
}
export function getDefaultString(defaultSpec: DefaultString): string {
@@ -136,7 +62,7 @@ export function getDefaultString(defaultSpec: DefaultString): string {
}
// a,g,h,A-Z,,,,-
-export function getRandomCharInSet(charset: string): string {
+function getRandomCharInSet(charset: string): string {
const set = stringToCharSet(charset)
let charIdx = Math.floor(Math.random() * set.len)
for (let range of set.ranges) {