@cybertale/form 2.0.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cybertale/form",
3
- "version": "2.0.4",
3
+ "version": "3.0.0",
4
4
  "description": "ECS interface for Web Development, CyberTale edition.",
5
5
  "author": "Joso Marich <jspmari@proton.me>",
6
6
  "license": "GPL-3.0-only",
@@ -30,13 +30,9 @@
30
30
  "dependencies": {
31
31
  "@cybertale/interface": "^2.0.6",
32
32
  "typescript": "^5.5.3",
33
- "vue": "^3.4.33",
34
- "vue-facing-decorator": "^3.0.4",
35
33
  "prompt-sync": "^4.2.0"
36
34
  },
37
35
  "devDependencies": {
38
- "@vitejs/plugin-vue": "^5.0.5",
39
- "@vue/compiler-sfc": "^3.4.33",
40
36
  "vite": "^5.3.4"
41
37
  },
42
38
  "scripts": {
@@ -1,73 +1,125 @@
1
1
  <template v-if="renderComponent">
2
- <button data-bs-toggle="tooltip" data-bs-placement="top"
3
- :data-bs-title="tooltipCase()"
4
- :hidden="specialCase()"
5
- :disabled="attributeCheck(statTypeEnum.Disabled)"
6
- :class="getValue(statTypeEnum.Design)"
7
- @click.prevent='regionType.RegionTypes[object.Region].ObjectTypes[object.ObjectEnum].ChooseSubType(object)'>
8
- {{ getValue(statTypeEnum.Label) }}
2
+ <button
3
+ data-bs-toggle="tooltip"
4
+ data-bs-placement="top"
5
+ :data-bs-title="tooltipText"
6
+ :hidden="isHidden"
7
+ :disabled="isDisabled"
8
+ :class="buttonClass"
9
+ @click.prevent="handleClick"
10
+ >
11
+ <span class="order-2">{{ buttonLabel }}</span>
12
+ <i v-if="showIcon" :class="iconClass"></i>
9
13
  </button>
10
14
  <slot></slot>
11
15
  </template>
12
16
 
17
+
13
18
  <script lang="ts">
14
19
  import { Component, Prop, Vue } from 'vue-facing-decorator'
15
- import { ObjectTemplate, ObjectType, StatTypeEnum, ObjectTypeEnum, RegionType, RegionEnum } from '@cybertale/interface'
20
+ import { ObjectTemplate, ObjectTypeEnum, RegionEnum, RegionType, StatTypeEnum } from '@cybertale/interface'
21
+
22
+ interface LabelData {
23
+ iconClass: string;
24
+ title: string;
25
+ }
16
26
  @Component
17
27
  export default class ButtonComponent extends Vue {
18
28
  @Prop() object!: ObjectTemplate
19
29
 
20
- statTypeEnum = StatTypeEnum
21
- objectTypeEnum = ObjectTypeEnum
22
- objectType = ObjectType
23
- regionType = RegionType
24
- regionEnum = RegionEnum
25
- renderComponent= false
26
-
27
- getValue (statEnum: number) : string {
28
- if (this.object) {
29
- if (this.object.Stats[this.statTypeEnum.Option] && this.isJSON(this.object.Stats[statEnum].Data)) {
30
- const data = JSON.parse(this.object.Stats[statEnum].Data)
31
- return data[Number(this.object.Stats[this.statTypeEnum.Option].Data)]
32
- } else {
33
- return this.object.Stats[statEnum].Data
34
- }
30
+ // Enums
31
+ StatTypeEnum = StatTypeEnum
32
+ ObjectTypeEnum = ObjectTypeEnum
33
+ RegionEnum = RegionEnum
34
+ btnClass = ''
35
+
36
+ renderComponent = false
37
+
38
+ // Computed properties
39
+ get tooltipText(): string | undefined {
40
+ return this.getStatData(StatTypeEnum.Tooltip)
41
+ }
42
+
43
+ get isHidden(): boolean {
44
+ return this.getStatData(StatTypeEnum.ElementType) === 'hidden'
45
+ }
46
+
47
+ get isDisabled(): boolean {
48
+ return !!this.getStatData(StatTypeEnum.Disabled, 'boolean')
49
+ }
50
+
51
+ get buttonClass(): string {
52
+ const temp = this.getValue(StatTypeEnum.Design) as string
53
+ return temp
54
+ }
55
+
56
+ get buttonLabel(): string {
57
+ if(this.showIcon){
58
+ const value = this.getValue(StatTypeEnum.Label) as LabelData
59
+ return value.title
35
60
  }
36
- return ''
61
+ return this.getValue(StatTypeEnum.Label) as string
37
62
  }
38
63
 
39
- isJSON (str: string): boolean {
40
- let temp = null
41
- try {
42
- temp = JSON.parse(str)
43
- } catch (e) {
44
- return false
64
+ get showIcon(): boolean {
65
+ return this.getStatData(StatTypeEnum.ElementType) === 'icon'
66
+ }
67
+
68
+ get iconClass(): string {
69
+ if(this.showIcon){
70
+ const value = this.getValue(StatTypeEnum.Label) as LabelData
71
+ return value.iconClass
45
72
  }
46
- return Array.isArray(temp)
73
+ return this.getValue(StatTypeEnum.Label)
74
+ }
75
+
76
+ // Methods
77
+ handleClick(): void {
78
+ const { Region, ObjectEnum } = this.object
79
+ RegionType.RegionTypes[Region].ObjectTypes[ObjectEnum].ChooseSubType(this.object)
47
80
  }
48
81
 
49
- tooltipCase () {
50
- if (this.object) {
51
- if (this.object.Stats[this.statTypeEnum.Tooltip]) {
52
- return this.object.Stats[this.statTypeEnum.Tooltip].Data
82
+ getValue( statEnum: StatTypeEnum, indexStatTypeEnum = StatTypeEnum.Option): string | LabelData {
83
+ const tempData:string = this.getStatData(statEnum) as string
84
+ if (!tempData) return '';
85
+
86
+ if (this.statIsDefined(indexStatTypeEnum) && this.isJSON(tempData)) {
87
+ const data = JSON.parse(tempData);
88
+ const optionData = this.getStatData(indexStatTypeEnum) as string
89
+ if(this.isJSON(optionData)){
90
+ const parsedOptionData = JSON.parse(optionData)[Number(this.object.Stats[StatTypeEnum.OptionIndices].Data)]
91
+ return data[Number(parsedOptionData)] || '';
53
92
  }
93
+ return data[Number(this.getStatData(indexStatTypeEnum))] || '';
54
94
  }
95
+
96
+ return tempData;
55
97
  }
56
98
 
57
- specialCase () : boolean {
58
- if (this.object.Stats[this.statTypeEnum.ElementType] === undefined) { return false }
59
- return this.object.Stats[this.statTypeEnum.ElementType].Data === 'hidden'
99
+ statIsDefined (statType: StatTypeEnum): boolean {
100
+ return !!this.object.Stats[statType]
60
101
  }
61
102
 
62
- attributeCheck (statType : number) : boolean | string {
63
- if (this.object.Stats[statType] === undefined) { return false }
64
- if (this.object.Stats[statType].Data === '') { return false }
65
- return this.object.Stats[statType].Data
103
+ getStatData(statType: StatTypeEnum, returnType: 'boolean' | 'string' = 'string'): boolean | string {
104
+ try {
105
+ const data = this.object.Stats[statType]?.Data ?? ''
106
+ return returnType === 'boolean' ? !!data : data
107
+ } catch (error) {
108
+ console.error(`Error accessing data for statType ${statType}:`, error)
109
+ return returnType === 'boolean' ? false : ''
110
+ }
111
+ }
112
+
113
+ isJSON(str: string): boolean {
114
+ try {
115
+ return Array.isArray(JSON.parse(str))
116
+ } catch {
117
+ return false
118
+ }
66
119
  }
67
120
  }
68
121
  </script>
69
122
 
70
- <!-- Add "scoped" attribute to limit CSS to this component only -->
71
123
  <style scoped>
72
-
124
+ /* Add your scoped styles here */
73
125
  </style>
@@ -1,15 +1,19 @@
1
1
  <template>
2
- <input class="form-control"
3
- :id="object?.Stats[statTypeEnum.Tag].Data"
4
- :required="attributeCheck(statTypeEnum.Required)"
5
- :disabled="attributeCheck(statTypeEnum.Disabled)"
6
- :autocomplete="returnIfExists(statTypeEnum.AutoComplete)"
7
- :class="object?.Stats[statTypeEnum.Design].Data+' '+validate()"
8
- :type="getValue(statTypeEnum.ElementType)"
9
- :value="labelToValue()"
10
- :placeholder="returnIfExists(statTypeEnum.Placeholder)"
11
- @input="regionType.RegionTypes[object?.Region].ObjectTypes[object?.ObjectEnum].ChooseSubType(object as ObjectTemplate, $event.target.value)">
12
- <div class="invalid-feedback">{{ returnIfExists(statTypeEnum.ErrorMessage) }}</div>
2
+ <input
3
+ class="form-control"
4
+ :id="getStatData(StatTypeEnum.Tag)"
5
+ :required="getStatData(StatTypeEnum.Required, 'boolean')"
6
+ :disabled="getStatData(StatTypeEnum.Disabled, 'boolean')"
7
+ :autocomplete="getStatData(StatTypeEnum.AutoComplete)"
8
+ :class="[getStatData(StatTypeEnum.Design), validationClass]"
9
+ :type="getInputType()"
10
+ :value="computedValue"
11
+ :placeholder="getStatData(StatTypeEnum.Placeholder)"
12
+ @input="handleInput"
13
+ />
14
+ <div v-if="showErrorMessage" class="invalid-feedback">
15
+ {{ getStatData(StatTypeEnum.ErrorMessage) }}
16
+ </div>
13
17
  </template>
14
18
 
15
19
  <script lang="ts">
@@ -20,74 +24,85 @@ import { ObjectTemplate, ObjectType, ObjectTypeEnum, RegionEnum, RegionType, Sta
20
24
  export default class FieldComponent extends Vue {
21
25
  @Prop() object!: ObjectTemplate
22
26
 
23
- statTypeEnum = StatTypeEnum
24
- objectTypeEnum = ObjectTypeEnum
25
- objectType = ObjectType
26
- regionType = RegionType
27
- regionEnum = RegionEnum
27
+ // Enums
28
+ StatTypeEnum = StatTypeEnum
29
+ ObjectTypeEnum = ObjectTypeEnum
30
+ RegionEnum = RegionEnum
28
31
 
29
- labelToValue(): string {
30
- if (this.returnIfExists(this.statTypeEnum.Tag).includes('label') && this.attributeCheck(this.statTypeEnum.Disabled)) {
31
- return this.returnIfExists(this.statTypeEnum.Label)
32
+ // Computed properties
33
+ get computedValue(): string {
34
+ if (this.isLabelDisabled) {
35
+ return this.getStatData(StatTypeEnum.Label)
32
36
  }
33
37
  return this.getValue(StatTypeEnum.Value, StatTypeEnum.ValueIndices)
34
38
  }
35
39
 
36
- getValue(statEnum: number, indexStatTypeEnum = StatTypeEnum.Option): string {
37
- if (this.object.Stats[statEnum]) {
38
- if (this.object.Stats[indexStatTypeEnum] && this.object.Stats[statEnum] && this.isJSON(this.object.Stats[statEnum].Data)) {
39
- const data = JSON.parse(this.object.Stats[statEnum].Data)
40
- return data[Number(this.object.Stats[indexStatTypeEnum].Data)]
41
- } else {
42
- return this.object.Stats[statEnum].Data
43
- }
44
- }
40
+ get isLabelDisabled(): boolean {
41
+ return this.getStatData(StatTypeEnum.Tag).includes('label') &&
42
+ this.getStatData(StatTypeEnum.Disabled, 'boolean')
43
+ }
44
+
45
+ get validationClass(): string {
46
+ const isValid = this.getStatData(StatTypeEnum.IsValid, 'boolean')
47
+ const errorMessage = this.getStatData(StatTypeEnum.ErrorMessage)
48
+
49
+ if (isValid === undefined || isValid === '') return ''
50
+ if (isValid) return 'is-valid'
51
+ if (errorMessage) return 'is-invalid'
45
52
  return ''
46
53
  }
47
54
 
48
- isJSON(str: string): boolean {
49
- try {
50
- const temp = JSON.parse(str)
51
- return Array.isArray(temp)
52
- } catch (e) {
53
- return false
55
+ get showErrorMessage(): boolean {
56
+ return this.validationClass === 'is-invalid'
57
+ }
58
+
59
+ // Methods
60
+ getInputType(): string {
61
+ return this.getValue(StatTypeEnum.ElementType)
62
+ }
63
+
64
+ handleInput(event: Event): void {
65
+ const target = event.target as HTMLInputElement
66
+ const { Region, ObjectEnum } = this.object
67
+ console.log(target.value)
68
+ RegionType.RegionTypes[Region].ObjectTypes[ObjectEnum].ChooseSubType(this.object, target.value)
69
+ }
70
+
71
+ getValue( statEnum: StatTypeEnum, indexStatTypeEnum = StatTypeEnum.Option): string {
72
+ const tempData:string = this.getStatData(statEnum)
73
+ if (!tempData) return '';
74
+
75
+ if (this.statIsDefined(indexStatTypeEnum) && this.isJSON(tempData)) {
76
+ const data = JSON.parse(tempData);
77
+ return data[Number(this.getStatData(indexStatTypeEnum))] || '';
54
78
  }
79
+
80
+ return tempData;
55
81
  }
56
82
 
57
- returnIfExists(tag: number): string {
58
- return this.object.Stats[tag]?.Data ?? ''
83
+ statIsDefined (statType: StatTypeEnum): boolean {
84
+ return !!this.object.Stats[statType]
59
85
  }
60
86
 
61
- validate(): string {
62
- if (this.object.Stats[this.statTypeEnum.IsValid] === undefined) { return '' }
63
- if (this.object.Stats[this.statTypeEnum.IsValid].Data === '') { return '' }
64
- if (this.object.Stats[this.statTypeEnum.IsValid].Data) { return 'is-valid' }
65
- if (this.object.Stats[this.statTypeEnum.ErrorMessage].Data === null) { return '' }
66
- if (this.object.Stats[this.statTypeEnum.ErrorMessage].Data !== '') { return 'is-invalid' }
67
- return ''
87
+ getStatData(statType: StatTypeEnum, returnType: 'boolean' | 'string' = 'string'): boolean | string {
88
+ try {
89
+ const data = this.object.Stats[statType]?.Data ?? ''
90
+ return returnType === 'boolean' ? !!data : data
91
+ } catch (error) {
92
+ return returnType === 'boolean' ? false : ''
93
+ }
68
94
  }
69
95
 
70
- attributeCheck(statType: number): boolean | string {
71
- if (this.object.Stats[statType] === undefined) { return false }
72
- if (this.object.Stats[statType].Data === '') { return false }
73
- return this.object.Stats[statType].Data
96
+ isJSON(str: string): boolean {
97
+ try {
98
+ return Array.isArray(JSON.parse(str))
99
+ } catch {
100
+ return false
101
+ }
74
102
  }
75
103
 
76
104
  tooltipCase(): string | undefined {
77
- return this.object?.Stats[this.statTypeEnum.Tooltip]?.Data
105
+ return this.object?.Stats[StatTypeEnum.Tooltip]?.Data
78
106
  }
79
107
  }
80
108
  </script>
81
-
82
- <style scoped>
83
- .form-check .form-check-input {
84
- float: none;
85
- }
86
- .form-check-input {
87
- margin-right: 1%;
88
- }
89
- .form-check-input:checked {
90
- background-color: #606467;
91
- border-color: #606467;
92
- }
93
- </style>
package/src/index.ts CHANGED
@@ -1,10 +1 @@
1
- import AlertComponent from './formComponents/AlertComponent.vue'
2
- import ButtonComponent from './formComponents/ButtonComponent.vue'
3
- import CheckBoxComponent from './formComponents/CheckBoxComponent.vue'
4
- import DataListComponent from './formComponents/DataListComponent.vue'
5
- import FieldComponent from './formComponents/FieldComponent.vue'
6
- import LabelComponent from './formComponents/LabelComponent.vue'
7
- import RadioComponent from './formComponents/RadioComponent.vue'
8
- import SelectListComponent from './formComponents/SelectListComponent.vue'
9
-
10
- export { AlertComponent, ButtonComponent, CheckBoxComponent, DataListComponent, FieldComponent, LabelComponent, RadioComponent, SelectListComponent }
1
+ export * from './primitives'
@@ -0,0 +1,8 @@
1
+ import { GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ export function buildAlertModel(object: ObjectTemplate) {
4
+ return {
5
+ className: GetStringStat(object, StatTypeEnum.Design),
6
+ text: GetStringStat(object, StatTypeEnum.Label)
7
+ }
8
+ }
@@ -0,0 +1,48 @@
1
+ import { GetStatData, GetStringStat, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { getLabelData } from './shared'
4
+ import { TooltipData } from './types'
5
+
6
+ export function buildButtonModel(object: ObjectTemplate, currentPath = '') {
7
+ const tooltip = GetValue(object, StatTypeEnum.Tooltip) as TooltipData | string
8
+ const tooltipToggleBy = typeof tooltip === 'string' ? 'tooltip' : tooltip.toggleBy
9
+ const tooltipText = typeof tooltip === 'string' ? tooltip : tooltip.value
10
+ const labelValue = GetValue(object, StatTypeEnum.Label)
11
+ const labelData = getLabelData(labelValue)
12
+ const tag = GetStringStat(object, StatTypeEnum.Tag)
13
+
14
+ let label = ''
15
+ if (labelData && 'title' in labelData) {
16
+ label = labelData.title
17
+ } else {
18
+ label = labelValue as string
19
+ }
20
+
21
+ const lowerLabel = label.toLowerCase()
22
+ if ((tag === 'buttonDelete' || lowerLabel.includes('delete') || lowerLabel.includes('izbri\u0161i')) && !currentPath.includes('add')) {
23
+ label = '<i class="fa-solid fa-trash-alt"></i> ' + label
24
+ } else if (tag === 'buttonEdit' || lowerLabel.includes('edit') || lowerLabel.includes('uredi')) {
25
+ label = '<i class="fa-solid fa-edit"></i> ' + label
26
+ } else if (tag === 'buttonMap' || lowerLabel.includes('kart')) {
27
+ label = '<i class="fa-solid fa-map-marker-alt"></i> ' + label
28
+ }
29
+
30
+ const showIcon = GetStatData(object, StatTypeEnum.ElementType) === 'icon'
31
+ const iconClass = showIcon && labelData ? labelData.iconClass : (labelValue as string)
32
+ const styleData = showIcon && labelData ? labelData.styleData : (labelValue as string)
33
+ const contentClass = showIcon && labelData ? labelData.contentClass : ''
34
+
35
+ return {
36
+ tooltipToggleBy,
37
+ tooltipText,
38
+ isHidden: GetStatData(object, StatTypeEnum.ElementType) === 'hidden',
39
+ isDisabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
40
+ buttonClass: GetValue(object, StatTypeEnum.Design) as string,
41
+ buttonLabel: label,
42
+ showIcon,
43
+ iconClass,
44
+ styleData,
45
+ contentClass,
46
+ contentValue: ''
47
+ }
48
+ }
@@ -0,0 +1,25 @@
1
+ import {
2
+ GetStatData,
3
+ GetStringStat,
4
+ GetValidationClass,
5
+ GetValue,
6
+ ObjectTemplate,
7
+ StatTypeEnum
8
+ } from '@cybertale/interface'
9
+
10
+ import { applyValue } from './shared'
11
+
12
+ export function buildCheckBoxModel(object: ObjectTemplate) {
13
+ return {
14
+ designClass: GetStringStat(object, StatTypeEnum.Design),
15
+ checked: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
16
+ name: GetStringStat(object, StatTypeEnum.Tag),
17
+ id: GetStringStat(object, StatTypeEnum.Tag),
18
+ required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
19
+ disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
20
+ label: GetStringStat(object, StatTypeEnum.Label),
21
+ validationClass: GetValidationClass(object),
22
+ errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
23
+ select: (checked: boolean) => applyValue(object, checked)
24
+ }
25
+ }
@@ -0,0 +1,35 @@
1
+ import {
2
+ GetRawStat,
3
+ GetStatData,
4
+ GetStringStat,
5
+ GetValidationClass,
6
+ GetValue,
7
+ ObjectTemplate,
8
+ StatTypeEnum
9
+ } from '@cybertale/interface'
10
+
11
+ import { applyValue } from './shared'
12
+
13
+ export function buildDataListModel(object: ObjectTemplate) {
14
+ return {
15
+ belongsTo: GetStringStat(object, StatTypeEnum.BelongsTo),
16
+ tag: GetStringStat(object, StatTypeEnum.Tag),
17
+ name: GetStringStat(object, StatTypeEnum.Name),
18
+ designClass: GetStringStat(object, StatTypeEnum.Design),
19
+ required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
20
+ disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
21
+ type: GetStringStat(object, StatTypeEnum.ElementType),
22
+ placeholder: GetStringStat(object, StatTypeEnum.Placeholder),
23
+ validationClass: GetValidationClass(object),
24
+ errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
25
+ rawValue: GetRawStat(object, StatTypeEnum.Value),
26
+ selectedValue: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
27
+ itemListRaw: GetStringStat(object, StatTypeEnum.ItemList),
28
+ setItemListRaw: (value: string) => {
29
+ if (object.Stats?.[StatTypeEnum.ItemList]) {
30
+ object.Stats[StatTypeEnum.ItemList].Data = value
31
+ }
32
+ },
33
+ select: (value: string) => applyValue(object, value)
34
+ }
35
+ }
@@ -0,0 +1,30 @@
1
+ import { GetStatData, GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { applyValue } from './shared'
4
+
5
+ export function buildFieldModel(object: ObjectTemplate) {
6
+ return {
7
+ tag: GetStatData(object, StatTypeEnum.Tag) as string,
8
+ label: GetStatData(object, StatTypeEnum.Label) as string,
9
+ required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
10
+ disabled: !!GetValue(object, StatTypeEnum.Disabled),
11
+ readOnly: GetStatData(object, StatTypeEnum.ReadOnly, 'boolean') as boolean,
12
+ autocomplete: GetStatData(object, StatTypeEnum.AutoComplete) as string,
13
+ type: GetValue(object, StatTypeEnum.ElementType) as string,
14
+ value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices) as string,
15
+ placeholder: GetStatData(object, StatTypeEnum.Placeholder) as string,
16
+ maxLength: GetStatData(object, StatTypeEnum.MaxLength) as string,
17
+ minLength: GetStatData(object, StatTypeEnum.MinLength) as string,
18
+ min: GetStatData(object, StatTypeEnum.Min) as string,
19
+ max: GetStatData(object, StatTypeEnum.Max) as string,
20
+ step: GetStatData(object, StatTypeEnum.Step) as string,
21
+ pattern: GetStatData(object, StatTypeEnum.Pattern) as string,
22
+ helpText: GetStatData(object, StatTypeEnum.HelpText) as string,
23
+ leadingIcon: GetStatData(object, StatTypeEnum.LeadingIcon) as string,
24
+ trailingIcon: GetStatData(object, StatTypeEnum.TrailingIcon) as string,
25
+ validationClass: GetValidationClass(object),
26
+ bootstrapClass: GetValue(object, StatTypeEnum.Design) as string,
27
+ errorMessage: GetStatData(object, StatTypeEnum.ErrorMessage) as string,
28
+ select: (value: string) => applyValue(object, value)
29
+ }
30
+ }
@@ -0,0 +1,13 @@
1
+ export * from './types'
2
+ export * from './alert'
3
+ export * from './textArea'
4
+ export * from './radio'
5
+ export * from './checkBox'
6
+ export * from './select'
7
+ export * from './label'
8
+ export * from './button'
9
+ export * from './input'
10
+ export * from './dataList'
11
+ export * from './field'
12
+ export * from './markdown'
13
+ export * from './modalList'
@@ -0,0 +1,26 @@
1
+ import {
2
+ GetStatData,
3
+ GetStringStat,
4
+ GetValidationClass,
5
+ GetValue,
6
+ ObjectTemplate,
7
+ StatTypeEnum
8
+ } from '@cybertale/interface'
9
+
10
+ import { applyValue } from './shared'
11
+
12
+ export function buildInputModel(object: ObjectTemplate) {
13
+ return {
14
+ id: GetStringStat(object, StatTypeEnum.Tag),
15
+ name: GetStringStat(object, StatTypeEnum.Tag),
16
+ type: (GetValue(object, StatTypeEnum.ElementType) as string) || 'text',
17
+ placeholder: GetStringStat(object, StatTypeEnum.Placeholder),
18
+ required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
19
+ disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
20
+ readOnly: GetStatData(object, StatTypeEnum.ReadOnly, 'boolean') as boolean,
21
+ autocomplete: GetStringStat(object, StatTypeEnum.AutoComplete),
22
+ value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
23
+ validationClass: GetValidationClass(object),
24
+ select: (value: string) => applyValue(object, value)
25
+ }
26
+ }
@@ -0,0 +1,87 @@
1
+ import { GetStatData, GetStringStat, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { getLabelData } from './shared'
4
+
5
+ function hexToRgb(hex: string) {
6
+ const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
7
+ hex = hex.replace(shorthandRegex, (_m, r, g, b) => r + r + g + g + b + b)
8
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
9
+ return result
10
+ ? {
11
+ r: parseInt(result[1], 16),
12
+ g: parseInt(result[2], 16),
13
+ b: parseInt(result[3], 16)
14
+ }
15
+ : null
16
+ }
17
+
18
+ function getLuminance(rgb: { r: number; g: number; b: number }) {
19
+ const a = [rgb.r, rgb.g, rgb.b].map((v) => {
20
+ v /= 255
21
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)
22
+ })
23
+ return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722
24
+ }
25
+
26
+ function getContrastRatio(luminance1: number, luminance2: number) {
27
+ const lightest = Math.max(luminance1, luminance2)
28
+ const darkest = Math.min(luminance1, luminance2)
29
+ return (lightest + 0.05) / (darkest + 0.05)
30
+ }
31
+
32
+ function isDarkBackground(bgHex: string) {
33
+ const bgRgb = hexToRgb(bgHex)
34
+ if (!bgRgb) return false
35
+ const bgLuminance = getLuminance(bgRgb)
36
+ const whiteLuminance = getLuminance({ r: 255, g: 255, b: 255 })
37
+ const blackLuminance = getLuminance({ r: 0, g: 0, b: 0 })
38
+
39
+ const whiteContrast = getContrastRatio(bgLuminance, whiteLuminance)
40
+ const blackContrast = getContrastRatio(bgLuminance, blackLuminance)
41
+
42
+ return whiteContrast > blackContrast
43
+ }
44
+
45
+ function extractHexColor(styleData: string): string {
46
+ const match = styleData.match(/background-color:\s*(#[0-9a-fA-F]{3,6})/)
47
+ return match ? match[1] : ''
48
+ }
49
+
50
+ export function buildLabelModel(object: ObjectTemplate) {
51
+ const showIcon = GetStatData(object, StatTypeEnum.ElementType) === 'icon'
52
+ const labelValue = GetValue(object, StatTypeEnum.Label)
53
+ const labelData = getLabelData(labelValue)
54
+ const tooltip = GetStringStat(object, StatTypeEnum.Tooltip)
55
+ const designClass = GetValue(object, StatTypeEnum.Design) as string
56
+
57
+ const label = showIcon && labelData ? labelData.title : (labelValue as string)
58
+ const iconClass = showIcon && labelData ? labelData.iconClass : ''
59
+ const markValue = showIcon && labelData ? labelData.markValue : ''
60
+ const styleData = showIcon && labelData ? labelData.styleData : ''
61
+ const contentClass = showIcon && labelData ? labelData.contentClass : ''
62
+ const contentValue = ''
63
+
64
+ let markClass = ''
65
+ if (showIcon && labelData) {
66
+ const backgroundColor = labelData.styleData
67
+ if (isDarkBackground(extractHexColor(backgroundColor))) {
68
+ markClass = labelData.markClass + ' text-white'
69
+ } else {
70
+ markClass = labelData.markClass
71
+ }
72
+ }
73
+
74
+ return {
75
+ showIcon,
76
+ designClass,
77
+ label,
78
+ iconClass,
79
+ markValue,
80
+ markClass,
81
+ styleData,
82
+ contentValue,
83
+ contentClass,
84
+ hidden: GetValue(object, StatTypeEnum.ElementType) === 'hidden',
85
+ tooltip: tooltip || undefined
86
+ }
87
+ }
@@ -0,0 +1,16 @@
1
+ import { GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { applyValue, buildParsedStats } from './shared'
4
+
5
+ export function buildMarkdownModel(object: ObjectTemplate) {
6
+ const parsedStats = buildParsedStats(object)
7
+ return {
8
+ design: parsedStats[StatTypeEnum.Design],
9
+ placeholder: parsedStats[StatTypeEnum.Placeholder],
10
+ required: parsedStats[StatTypeEnum.Required],
11
+ disabled: parsedStats[StatTypeEnum.Disabled],
12
+ validationClass: GetValidationClass(object),
13
+ value: GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices),
14
+ select: (value: unknown) => applyValue(object, value)
15
+ }
16
+ }
@@ -0,0 +1,34 @@
1
+ import { GetValidationClass, GetValue, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { applyValue, buildParsedStats } from './shared'
4
+
5
+ export function buildModalListModel(object: ObjectTemplate) {
6
+ const parsedStats = buildParsedStats(object)
7
+ const value = GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices)
8
+ const valueName = value && typeof value === 'object' && 'name' in value
9
+ ? (value as { name: string }).name
10
+ : (value as string)
11
+ const valueIcon = value && typeof value === 'object' && 'id' in value
12
+ ? (value as { id: string }).id
13
+ : (value as string)
14
+
15
+ return {
16
+ design: parsedStats[StatTypeEnum.Design],
17
+ placeholder: parsedStats[StatTypeEnum.Placeholder],
18
+ required: parsedStats[StatTypeEnum.Required],
19
+ disabled: parsedStats[StatTypeEnum.Disabled],
20
+ elementType: parsedStats[StatTypeEnum.ElementType],
21
+ itemList: parsedStats[StatTypeEnum.ItemList],
22
+ name: parsedStats[StatTypeEnum.Name],
23
+ validationClass: GetValidationClass(object),
24
+ value,
25
+ valueName,
26
+ valueIcon,
27
+ setItemListRaw: (raw: string) => {
28
+ if (object.Stats?.[StatTypeEnum.ItemList]) {
29
+ object.Stats[StatTypeEnum.ItemList].Data = raw
30
+ }
31
+ },
32
+ select: (next: string) => applyValue(object, next)
33
+ }
34
+ }
@@ -0,0 +1,26 @@
1
+ import { GetRawStat, GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { applyValue } from './shared'
4
+ import { RadioOption } from './types'
5
+
6
+ export function buildRadioModel(object: ObjectTemplate) {
7
+ const itemListRaw = GetStringStat(object, StatTypeEnum.ItemList)
8
+ const name = GetStringStat(object, StatTypeEnum.Name)
9
+ const tag = GetStringStat(object, StatTypeEnum.Tag)
10
+ const isGroup = itemListRaw !== '' && name === ''
11
+ const items = isGroup ? (JSON.parse(itemListRaw) as RadioOption[]) : []
12
+
13
+ const isChecked = (candidate: unknown) => GetRawStat(object, StatTypeEnum.Value) === candidate
14
+
15
+ return {
16
+ className: GetStringStat(object, StatTypeEnum.Design),
17
+ isGroup,
18
+ items,
19
+ groupName: tag,
20
+ name,
21
+ singleValue: itemListRaw,
22
+ singleLabel: itemListRaw,
23
+ isChecked,
24
+ select: (value: unknown) => applyValue(object, value)
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import {
2
+ GetStatData,
3
+ GetStringStat,
4
+ GetValidationClass,
5
+ GetValue,
6
+ ObjectTemplate,
7
+ ParseJSON,
8
+ StatTypeEnum
9
+ } from '@cybertale/interface'
10
+
11
+ import { applyValue } from './shared'
12
+ import { SelectOption } from './types'
13
+
14
+ export function buildSelectModel(object: ObjectTemplate) {
15
+ const itemListRaw = GetStringStat(object, StatTypeEnum.ItemList)
16
+ const items = ParseJSON<SelectOption[]>(itemListRaw) ?? []
17
+ const selected = GetValue(object, StatTypeEnum.Value, StatTypeEnum.ValueIndices)
18
+
19
+ return {
20
+ name: GetStringStat(object, StatTypeEnum.Tag),
21
+ hidden: GetValue(object, StatTypeEnum.ElementType) === 'hidden',
22
+ required: GetStatData(object, StatTypeEnum.Required, 'boolean') as boolean,
23
+ disabled: GetStatData(object, StatTypeEnum.Disabled, 'boolean') as boolean,
24
+ autocomplete: GetStringStat(object, StatTypeEnum.AutoComplete),
25
+ validationClass: GetValidationClass(object),
26
+ errorMessage: GetStringStat(object, StatTypeEnum.ErrorMessage),
27
+ items,
28
+ isSelected: (id: string | number) => selected === id.toString(),
29
+ placeholderSelected: GetStatData(object, StatTypeEnum.Value, 'boolean') as boolean,
30
+ select: (value: string) => applyValue(object, value)
31
+ }
32
+ }
@@ -0,0 +1,26 @@
1
+ import { ObjectTemplate, ParseJSON, RegionType, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ import { LabelData } from './types'
4
+
5
+ export function applyValue(object: ObjectTemplate, value: unknown) {
6
+ RegionType.RegionTypes[object.Region]
7
+ .ObjectTypes[object.ObjectEnum]
8
+ .ChooseSubType(object, value)
9
+ }
10
+
11
+ export function buildParsedStats(object: ObjectTemplate): Record<number, any> {
12
+ const parsed: Record<number, any> = {}
13
+ const stats = object.Stats ?? {}
14
+ Object.entries(stats).forEach(([key, stat]) => {
15
+ const parsedValue = ParseJSON(stat.Data as string | null | undefined)
16
+ parsed[Number(key)] = parsedValue == null ? stat.Data : parsedValue
17
+ })
18
+ return parsed
19
+ }
20
+
21
+ export function getLabelData(value: unknown): LabelData | null {
22
+ if (typeof value === 'object' && value !== null) {
23
+ return value as LabelData
24
+ }
25
+ return null
26
+ }
@@ -0,0 +1,14 @@
1
+ import { GetStringStat, ObjectTemplate, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ export function buildTextAreaModel(object: ObjectTemplate) {
4
+ return {
5
+ label: GetStringStat(object, StatTypeEnum.Label),
6
+ tooltip: GetStringStat(object, StatTypeEnum.Tooltip),
7
+ value: GetStringStat(object, StatTypeEnum.Value),
8
+ setValue: (next: string) => {
9
+ if (object.Stats?.[StatTypeEnum.Value]) {
10
+ object.Stats[StatTypeEnum.Value].Data = next
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,28 @@
1
+ export interface LabelData {
2
+ styleData: string
3
+ iconClass: string
4
+ title: string
5
+ markValue: string
6
+ markClass: string
7
+ contentValue: string
8
+ contentClass: string
9
+ distanceFromSea: string
10
+ translate: string
11
+ number: string
12
+ }
13
+
14
+ export interface TooltipData {
15
+ toggleBy: string
16
+ value: string
17
+ translate?: string
18
+ }
19
+
20
+ export interface SelectOption {
21
+ id: string | number
22
+ name: string
23
+ }
24
+
25
+ export interface RadioOption {
26
+ id: string | number
27
+ name: string
28
+ }
@@ -0,0 +1,5 @@
1
+ import { StatTypeEnum } from '@cybertale/interface'
2
+
3
+ export class AlertComponentLogic {
4
+ statTypeEnum = StatTypeEnum
5
+ }
@@ -0,0 +1,19 @@
1
+ import { ObjectTemplate, ObjectType, ObjectTypeEnum, RegionType, RegionEnum, StatTypeEnum, GetStringStat } from '@cybertale/interface'
2
+
3
+ export class RadioComponentLogic {
4
+ statTypeEnum = StatTypeEnum
5
+ objectTypeEnum = ObjectTypeEnum
6
+ objectType = ObjectType
7
+ regionType = RegionType
8
+ regionEnum = RegionEnum
9
+
10
+ returnIfExists(object: ObjectTemplate, tag: number): string {
11
+ return GetStringStat(object, tag as StatTypeEnum)
12
+ }
13
+
14
+ handleInput(object: ObjectTemplate, value: string) {
15
+ this.regionType.RegionTypes[object.Region]
16
+ .ObjectTypes[object.ObjectEnum]
17
+ .ChooseSubType(object as ObjectTemplate, value)
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ import { ObjectType, ObjectTypeEnum, StatTypeEnum } from '@cybertale/interface'
2
+
3
+ export class TextAreaComponentLogic {
4
+ statTypeEnum = StatTypeEnum
5
+ objectTypeEnum = ObjectTypeEnum
6
+ objectType = ObjectType
7
+ }