Skip to content

Commit fa98f30

Browse files
authored
feat: initial values & getters for field/editor API (#1444)
# Initial values When passing a callback to the following methods at the very start of the app, it was called with `undefined` instead of its initial value - `sdk.field.onIsDisabledChanged` - `sdk.field.onSchemaErrorsChanged` - `sdk.editor.onLocaleSettingsChanged` - `sdk.editor.onShowDisabledFieldsChanged` This is now fixed and the callback is immediately invoked with the correct value. # Getters The following methods are added - `sdk.field.getIsDisabled()` - `sdk.field.getSchemaErrors()` - `sdk.editor.getLocaleSettings()` - `sdk.editor.getShowHiddenFields()` # Deprecation `sdk.editor.onShowDisabledFieldsChanged` is now deprecated and replaced by `sdk.editor.onShowHiddenFieldsChanged`
1 parent 2b00672 commit fa98f30

File tree

14 files changed

+186
-60
lines changed

14 files changed

+186
-60
lines changed

lib/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ function makeWindowAPI(channel: Channel, _data: any, currentGlobal: typeof globa
9999
}
100100

101101
function makeEditorAPI(channel: Channel, data: any) {
102-
const { editorInterface } = data
102+
const { editorInterface, editor } = data
103103
return {
104-
editor: createEditor(channel, editorInterface),
104+
editor: createEditor(channel, editorInterface, editor),
105105
}
106106
}
107107

lib/channel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class Channel {
5656

5757
addHandler<T extends unknown[]>(method: string, handler: (...args: T) => void) {
5858
if (!(method in this._messageHandlers)) {
59-
this._messageHandlers[method] = new Signal<T>()
59+
this._messageHandlers[method] = new Signal()
6060
}
6161
return this._messageHandlers[method].attach(handler)
6262
}

lib/editor.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,43 @@
11
import { EditorInterface, EditorLocaleSettings, SharedEditorSDK } from './types'
22
import { Channel } from './channel'
33
import { MemoizedSignal } from './signal'
4+
import { ConnectMessage } from './types/api.types'
45

56
export default function createEditor(
67
channel: Channel,
7-
editorInterface: EditorInterface
8+
editorInterface: EditorInterface,
9+
editorData: Exclude<ConnectMessage['editor'], undefined>
810
): SharedEditorSDK['editor'] {
9-
// @ts-expect-error Missing default value
10-
const _localeSettingsSygnal = new MemoizedSignal<[EditorLocaleSettings]>([undefined])
11-
// @ts-expect-error Missing default value
12-
const _showDisabledFieldsSygnal = new MemoizedSignal<[boolean]>([undefined])
11+
const localeSettingsSignal = new MemoizedSignal<[EditorLocaleSettings]>(editorData.localeSettings)
12+
const showHiddenFieldsSignal = new MemoizedSignal<[boolean]>(editorData.showHiddenFields)
1313

1414
channel.addHandler('localeSettingsChanged', (settings: EditorLocaleSettings) => {
15-
_localeSettingsSygnal.dispatch(settings)
15+
localeSettingsSignal.dispatch(settings)
1616
})
1717

18-
channel.addHandler('showDisabledFieldsChanged', (showDisabledFields: boolean) => {
19-
_showDisabledFieldsSygnal.dispatch(showDisabledFields)
18+
channel.addHandler('showHiddenFieldsChanged', (showHiddenFields: boolean) => {
19+
showHiddenFieldsSignal.dispatch(showHiddenFields)
2020
})
2121

2222
return {
2323
editorInterface,
24-
onLocaleSettingsChanged: (handler: (localeSettings: EditorLocaleSettings) => void) => {
25-
return _localeSettingsSygnal.attach(handler)
24+
getLocaleSettings(): EditorLocaleSettings {
25+
return localeSettingsSignal.getMemoizedArgs()[0]
2626
},
27-
onShowDisabledFieldsChanged: (handler: (showDisabledFields: boolean) => void) => {
28-
return _showDisabledFieldsSygnal.attach(handler)
27+
onLocaleSettingsChanged: (handler) => {
28+
return localeSettingsSignal.attach(handler)
29+
},
30+
/**
31+
* @deprecated
32+
*/
33+
onShowDisabledFieldsChanged: (handler) => {
34+
return showHiddenFieldsSignal.attach(handler)
35+
},
36+
getShowHiddenFields(): boolean {
37+
return showHiddenFieldsSignal.getMemoizedArgs()[0]
38+
},
39+
onShowHiddenFieldsChanged: (handler) => {
40+
return showHiddenFieldsSignal.attach(handler)
2941
},
3042
}
3143
}

lib/entry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Channel } from './channel'
22
import { MemoizedSignal } from './signal'
3-
import { EntryAPI, EntryFieldInfo, EntrySys, Metadata, TaskAPI } from './types'
3+
import { EntryAPI, EntryFieldAPI, EntryFieldInfo, EntrySys, Metadata, TaskAPI } from './types'
44

55
const taskMethods: Array<keyof TaskAPI> = [
66
'getTask',
@@ -14,7 +14,7 @@ export default function createEntry(
1414
channel: Channel,
1515
entryData: any,
1616
fieldInfo: EntryFieldInfo[],
17-
createEntryField: Function
17+
createEntryField: (info: EntryFieldInfo) => EntryFieldAPI
1818
): EntryAPI {
1919
let sys = entryData.sys
2020
const sysChanged = new MemoizedSignal<[EntrySys]>(sys)

lib/field-locale.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Channel } from './channel'
22
import { MemoizedSignal } from './signal'
3-
import { FieldAPI, FieldInfo, Items } from './types'
3+
import { FieldAPI, FieldInfo, Items, SerializedJSONValue } from './types'
44
import { ValidationError } from './types/validation-error'
55

66
export default class FieldLocale implements FieldAPI {
@@ -15,7 +15,7 @@ export default class FieldLocale implements FieldAPI {
1515
private _valueSignal: MemoizedSignal<[any]>
1616
private _isDisabledSignal: MemoizedSignal<[boolean]>
1717
private _schemaErrorsChangedSignal: MemoizedSignal<[ValidationError[]]>
18-
private _channel: any
18+
private _channel: Channel
1919

2020
constructor(channel: Channel, info: FieldInfo) {
2121
this.id = info.id
@@ -27,10 +27,8 @@ export default class FieldLocale implements FieldAPI {
2727

2828
this._value = info.value
2929
this._valueSignal = new MemoizedSignal(this._value)
30-
// @ts-expect-error Missing default value
31-
this._isDisabledSignal = new MemoizedSignal<[boolean]>(undefined)
32-
// @ts-expect-error Missing default value
33-
this._schemaErrorsChangedSignal = new MemoizedSignal<[ValidationError[]]>(undefined)
30+
this._isDisabledSignal = new MemoizedSignal<[boolean]>(info.isDisabled)
31+
this._schemaErrorsChangedSignal = new MemoizedSignal<[ValidationError[]]>(info.schemaErrors)
3432
this._channel = channel
3533

3634
channel.addHandler('valueChanged', (id: string, locale: string, value: any) => {
@@ -63,15 +61,20 @@ export default class FieldLocale implements FieldAPI {
6361
return this._value
6462
}
6563

66-
setValue(value: any) {
64+
async setValue(value: any) {
6765
this._value = value
6866
this._valueSignal.dispatch(value)
69-
return this._channel.call('setValue', this.id, this.locale, value)
67+
return await this._channel.call<SerializedJSONValue | undefined>(
68+
'setValue',
69+
this.id,
70+
this.locale,
71+
value
72+
)
7073
}
7174

72-
removeValue() {
75+
async removeValue() {
7376
this._value = undefined
74-
return this._channel.call('removeValue', this.id, this.locale)
77+
await this._channel.call('removeValue', this.id, this.locale)
7578
}
7679

7780
setInvalid(isInvalid: boolean) {
@@ -82,10 +85,18 @@ export default class FieldLocale implements FieldAPI {
8285
return this._valueSignal.attach(handler)
8386
}
8487

88+
getIsDisabled(): boolean {
89+
return this._isDisabledSignal.getMemoizedArgs()[0]
90+
}
91+
8592
onIsDisabledChanged(handler: (isDisabled: boolean) => any) {
8693
return this._isDisabledSignal.attach(handler)
8794
}
8895

96+
getSchemaErrors(): ValidationError[] {
97+
return this._schemaErrorsChangedSignal.getMemoizedArgs()[0]
98+
}
99+
89100
onSchemaErrorsChanged(handler: (errors: ValidationError[]) => void) {
90101
return this._schemaErrorsChangedSignal.attach(handler)
91102
}

lib/field.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export default class Field implements EntryFieldAPI {
3232
items: info.items,
3333
locale,
3434
value: info.values[locale],
35+
isDisabled: info.isDisabled[locale],
36+
schemaErrors: info.schemaErrors[locale],
3537
})
3638

3739
return { ...acc, [locale]: fieldLocale }
@@ -46,12 +48,12 @@ export default class Field implements EntryFieldAPI {
4648
return this._getFieldLocale(locale).getValue()
4749
}
4850

49-
setValue(value: any, locale?: string) {
50-
return this._getFieldLocale(locale).setValue(value)
51+
async setValue(value: any, locale?: string) {
52+
return await this._getFieldLocale(locale).setValue(value)
5153
}
5254

53-
removeValue(locale?: string) {
54-
return this.setValue(undefined, locale)
55+
async removeValue(locale?: string) {
56+
await this.setValue(undefined, locale)
5557
}
5658

5759
onValueChanged(locale: string | ((value: any) => void), handler?: (value: any) => void) {

lib/signal.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,8 @@ export class MemoizedSignal<T extends unknown[]> extends Signal<T> {
5050
listener(...this._memoizedArgs)
5151
return detachListener
5252
}
53+
54+
getMemoizedArgs(): T {
55+
return this._memoizedArgs
56+
}
5357
}

lib/types/api.types.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,56 @@ export interface EditorLocaleSettings {
125125
export interface SharedEditorSDK {
126126
editor: {
127127
editorInterface: EditorInterface
128+
129+
/**
130+
* Returns the current locale settings
131+
*
132+
* The locale setting can change. To always work with the latest settings, use `onLocaleSettingsChanged`.
133+
*/
134+
getLocaleSettings(): EditorLocaleSettings
135+
136+
/**
137+
* Subscribes to changes of the editor's locale settings
138+
*
139+
* @param callback Function that is called every time the locale settings change. Called immidiately with the current setting.
140+
* @returns Function to unsubscribe. `callback` won't be called anymore.
141+
*/
128142
onLocaleSettingsChanged: (
129143
callback: (localeSettings: EditorLocaleSettings) => void
130144
) => () => void
131-
onShowDisabledFieldsChanged: (callback: (showDisabledFields: boolean) => any) => () => void
145+
146+
/**
147+
* Subscribes to changes of whether or not disabled fields are displayed
148+
*
149+
* @param callback Function that is called every time the setting whether or not disabled fields are displayed changes. Called immediately with the current state.
150+
* @returns Function to unsubscribe. `callback` won't be called anymore.
151+
* @deprecated Use {@link onShowHiddenFieldsChanged} instead
152+
*/
153+
onShowDisabledFieldsChanged: (callback: (showDisabledFields: boolean) => void) => () => void
154+
155+
/**
156+
* Returns whether or not hidden fields are displayed
157+
*
158+
* This setting can change. To always work with the latest settings, use `onShowHiddenFieldsChanged`.
159+
*/
160+
getShowHiddenFields(): boolean
161+
162+
/**
163+
* Subscribes to changes of whether or not hidden fields are displayed
164+
*
165+
* @param callback Function that is called every time the setting whether or not hidden fields are displayed changes. Called immediately with the current state.
166+
* @returns Function to unsubscribe. `callback` won't be called anymore.
167+
*/
168+
onShowHiddenFieldsChanged: (callback: (showHiddenFields: boolean) => void) => () => void
132169
}
133-
/** Allows to read and update the value of any field of the current entry and to get the entry's metadata */
170+
171+
/**
172+
* Allows to read and update the value of any field of the current entry and to get the entry's metadata
173+
*/
134174
entry: EntryAPI
135-
/** Information about the content type of the entry. */
175+
/**
176+
* Information about the content type of the entry.
177+
*/
136178
contentType: ContentTypeAPI
137179
}
138180

@@ -274,6 +316,10 @@ export interface ConnectMessage {
274316
ids: IdsAPI
275317
contentType: ContentTypeAPI
276318
editorInterface?: EditorInterface
319+
editor?: {
320+
localeSettings: EditorLocaleSettings
321+
showHiddenFields: boolean
322+
}
277323
entry: {
278324
sys: EntrySys
279325
metadata?: Metadata

lib/types/field-locale.types.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,34 @@ export interface FieldAPI {
2929
* the returned function can be called to remove the handler function
3030
**/
3131
onValueChanged: (callback: (value: any) => void) => () => void
32-
/** Calls the callback when the disabled status of the field changes.
33-
* the returned function can be called to remove the handler function
34-
**/
32+
33+
/**
34+
* Returns whether the current field is disabled
35+
*
36+
* The disabled state can change. To always work with the latest state, use `onIsDisabledChanged`.
37+
*/
38+
getIsDisabled(): boolean
39+
40+
/**
41+
* Subscribes to changes to this field's disabled state
42+
*
43+
* @param callback Function that is called every time this field's disabled state changes. Called immidiately with the current state.
44+
* @returns Function to unsubscribe. `callback` won't be called anymore.
45+
*/
3546
onIsDisabledChanged: (callback: (isDisabled: boolean) => void) => () => void
36-
/** Calls the callback immediately with the current validation errors and whenever the field is re-validated.
37-
* the returned function can be called to remove the handler function
38-
**/
47+
48+
/**
49+
* Returns the field's validation errors
50+
*
51+
* The schema errors can change. To always work with the latest errors, use `onSchemaErrorsChanged`.
52+
*/
53+
getSchemaErrors(): ValidationError[]
54+
55+
/**
56+
* Subscribes to schema errors
57+
*
58+
* @param callback Function that is called every time the schema errors change. Called immediately with the current errors.
59+
* @returns Function to unsubscribe. `callback` won't be called anymore.
60+
*/
3961
onSchemaErrorsChanged: (callback: (errors: ValidationError[]) => void) => () => void
4062
}

lib/types/field.types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Items, SerializedJSONValue } from './utils'
22
import { FieldAPI } from './field-locale.types'
33
import { ContentTypeFieldValidation } from './entities'
4+
import { ValidationError } from './validation-error'
45

56
export interface FieldInfo {
67
id: string
@@ -10,6 +11,8 @@ export interface FieldInfo {
1011
validations: ContentTypeFieldValidation[]
1112
items?: Items
1213
value: any
14+
isDisabled: boolean
15+
schemaErrors: ValidationError[]
1316
}
1417

1518
export interface EntryFieldInfo {
@@ -20,6 +23,8 @@ export interface EntryFieldInfo {
2023
validations: ContentTypeFieldValidation[]
2124
items?: Items
2225
values: { [locale: string]: any }
26+
isDisabled: { [locale: string]: boolean }
27+
schemaErrors: { [locale: string]: ValidationError[] }
2328
}
2429

2530
export interface EntryFieldAPI {

0 commit comments

Comments
 (0)