diff --git a/packages/sdk/src/controllers/VariableController.ts b/packages/sdk/src/controllers/VariableController.ts index e2fc33cd..3c22a62c 100644 --- a/packages/sdk/src/controllers/VariableController.ts +++ b/packages/sdk/src/controllers/VariableController.ts @@ -1,8 +1,12 @@ import { EditorAPI, Id } from '../types/CommonTypes'; import { ConnectorRegistration } from '../types/ConnectorTypes'; import { + DateRestriction, + DateVariablePropertiesDeltaUpdate, + Day, ListVariable, ListVariableItem, + Locale, Variable, VariableType, NumberVariablePropertiesDeltaUpdate, @@ -24,7 +28,7 @@ class NumberVariable { */ setMinimum = async (id: string, minimum: number | null) => { const update = { minValue: { value: minimum } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -35,7 +39,7 @@ class NumberVariable { */ setMaximum = async (id: string, maximum: number | null) => { const update = { maxValue: { value: maximum } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -46,7 +50,7 @@ class NumberVariable { */ setShowStepper = async (id: string, showStepper: boolean) => { const update = { showStepper: { value: showStepper } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -57,7 +61,7 @@ class NumberVariable { */ setStepSize = async (id: string, stepSize: number) => { const update = { stepSize: { value: stepSize } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -68,7 +72,7 @@ class NumberVariable { */ setThousandsSeparator = async (id: string, thousandsSeparator: '' | '.' | ',' | ' ') => { const update = { thousandsSeparator: { value: thousandsSeparator } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -79,7 +83,7 @@ class NumberVariable { */ setDecimalSeparator = async (id: string, decimalSeparator: '' | '.' | ',' | ' ') => { const update = { decimalSeparator: { value: decimalSeparator } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -90,7 +94,7 @@ class NumberVariable { */ setDecimalCharacterStyle = async (id: string, characterStyleId: string | null) => { const update = { decimalCharacterStyleId: { value: characterStyleId } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; /** @@ -101,15 +105,80 @@ class NumberVariable { */ setNumberOfDecimals = async (id: string, numberOfDecimals: 0 | 1 | 2 | 3 | 4) => { const update = { numberOfDecimals: { value: numberOfDecimals } }; - return this.applyNumberVariablePropertiesUpdate(id, update); + return this.applyPropertiesUpdate(id, update); }; - private async applyNumberVariablePropertiesUpdate(id: string, update: NumberVariablePropertiesDeltaUpdate) { + private async applyPropertiesUpdate(id: string, update: NumberVariablePropertiesDeltaUpdate) { const res = await this.#editorAPI; const result = await res.updateNumberVariableProperties(id, JSON.stringify(update)); return getEditorResponseData(result); } } + +class DateVariable { + #editorAPI: EditorAPI; + + constructor(editorAPI: EditorAPI) { + this.#editorAPI = editorAPI; + } + + /** + * @experimental This method sets the display format for a date variable. + * @param id The id of the date variable to update + * @param displayFormat The display format for the date variable + */ + setDisplayFormat = async (id: string, displayFormat: string) => { + const update = { displayFormat: { value: displayFormat } }; + this.applyPropertiesUpdate(id, update); + }; + + /** + * @experimental This method sets the locale for a date variable. + * @param id The id of the date variable to update + * @param locale The locale for the date variable + */ + setLocale = async (id: string, locale: Locale) => { + const update = { locale: { value: locale } }; + this.applyPropertiesUpdate(id, update); + }; + + /** + * @experimental This method sets or clears the start date for a date variable. + * @param id The id of the date variable to update + * @param date The start date for the date variable + */ + setStartDate = async (id: string, date: DateRestriction | null) => { + const update = { startDate: { value: date } }; + this.applyPropertiesUpdate(id, update); + }; + + /** + * @experimental This method sets or clears the end date for a date variable. + * @param id The id of the date variable to update + * @param date The end date for the date variable + */ + setEndDate = async (id: string, date: DateRestriction | null) => { + const update = { endDate: { value: date } }; + this.applyPropertiesUpdate(id, update); + }; + + /** + * @experimental This method sets or clears the excluded days for a date variable. + * @param id The id of the date variable to update + * @param excludedDays The excluded days for the date variable + */ + setExcludedDays = async (id: string, excludedDays: Day[] | null) => { + const update = { excludedDays: { value: excludedDays } }; + this.applyPropertiesUpdate(id, update); + }; + + private async applyPropertiesUpdate(id: string, update: DateVariablePropertiesDeltaUpdate) { + const res = await this.#editorAPI; + const result = await res.updateDateVariableProperties(id, JSON.stringify(update)); + return getEditorResponseData(result); + } +} + /** * The VariableController is responsible for all communication regarding the variables. * Methods inside this controller can be called by `window.SDK.variable.{method-name}` @@ -121,6 +190,7 @@ export class VariableController { #editorAPI: EditorAPI; number: NumberVariable; + date: DateVariable; /** * @ignore @@ -128,6 +198,7 @@ export class VariableController { constructor(editorAPI: EditorAPI) { this.#editorAPI = editorAPI; this.number = new NumberVariable(this.#editorAPI); + this.date = new DateVariable(this.#editorAPI); } /** diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 77a7be37..3c528313 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -58,8 +58,12 @@ export type { BooleanVariable, NumberVariable, ConnectorImageVariableSource, + DateVariable, + DateRestriction, + RelativeDate, + AbsoluteDate, } from './types/VariableTypes'; -export { VariableType } from './types/VariableTypes'; +export { VariableType, Day, Locale } from './types/VariableTypes'; export type { Color, DocumentColor, ColorUpdate } from './types/ColorStyleTypes'; diff --git a/packages/sdk/src/tests/controllers/VariableController.test.ts b/packages/sdk/src/tests/controllers/VariableController.test.ts index d74d6f61..c0a5c65a 100644 --- a/packages/sdk/src/tests/controllers/VariableController.test.ts +++ b/packages/sdk/src/tests/controllers/VariableController.test.ts @@ -1,5 +1,13 @@ import { VariableController } from '../../controllers/VariableController'; -import { ImageVariable, ListVariable, ListVariableItem, Variable, VariableType } from '../../types/VariableTypes'; +import { + Day, + ImageVariable, + ListVariable, + ListVariableItem, + Locale, + Variable, + VariableType, +} from '../../types/VariableTypes'; import { EditorAPI } from '../../types/CommonTypes'; import { getEditorResponseData, castToEditorResponse } from '../../utils/EditorResponseData'; import { ConnectorRegistration, ConnectorRegistrationSource } from '../../types/ConnectorTypes'; @@ -69,6 +77,7 @@ describe('VariableController', () => { setVariableSource: async () => getEditorResponseData(castToEditorResponse(null)), getImageVariableConnectorId: async () => getEditorResponseData(castToEditorResponse('connectorId')), setImageVariableConnector: async () => getEditorResponseData(castToEditorResponse('newConnectorId')), + updateDateVariableProperties: async () => getEditorResponseData(castToEditorResponse(null)), updateNumberVariableProperties: async () => getEditorResponseData(castToEditorResponse(null)), }; @@ -95,6 +104,7 @@ describe('VariableController', () => { jest.spyOn(mockEditorApi, 'setVariableSource'); jest.spyOn(mockEditorApi, 'getImageVariableConnectorId'); jest.spyOn(mockEditorApi, 'setImageVariableConnector'); + jest.spyOn(mockEditorApi, 'updateDateVariableProperties'); jest.spyOn(mockEditorApi, 'updateNumberVariableProperties'); }); @@ -258,6 +268,47 @@ describe('VariableController', () => { expect(mockEditorApi.setVariableValue).toHaveBeenCalledWith(varId, null); }); + it('updates the date start date', async () => { + await mockedVariableController.date.setStartDate('1', { offset: 4, type: 'relative' }); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledTimes(1); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledWith( + '1', + JSON.stringify({ startDate: { value: { offset: 4, type: 'relative' } } }), + ); + }); + it('updates the date end date', async () => { + await mockedVariableController.date.setEndDate('1', { value: '2022-12-13', type: 'absolute' }); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledTimes(1); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledWith( + '1', + JSON.stringify({ endDate: { value: { value: '2022-12-13', type: 'absolute' } } }), + ); + }); + it('updates the date excluded days', async () => { + await mockedVariableController.date.setExcludedDays('1', [Day.Monday, Day.Friday]); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledTimes(1); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledWith( + '1', + JSON.stringify({ excludedDays: { value: [Day.Monday, Day.Friday] } }), + ); + }); + it('updates the date locale', async () => { + await mockedVariableController.date.setLocale('1', Locale.es_ES); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledTimes(1); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledWith( + '1', + JSON.stringify({ locale: { value: Locale.es_ES } }), + ); + }); + it('updates the date format', async () => { + await mockedVariableController.date.setDisplayFormat('1', 'yyyy-MM-dd'); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledTimes(1); + expect(mockEditorApi.updateDateVariableProperties).toHaveBeenCalledWith( + '1', + JSON.stringify({ displayFormat: { value: 'yyyy-MM-dd' } }), + ); + }); + it('updates the minimum variable value', async () => { await mockedVariableController.number.setMinimum('1', 20); expect(mockEditorApi.updateNumberVariableProperties).toHaveBeenCalledTimes(1); diff --git a/packages/sdk/src/types/VariableTypes.ts b/packages/sdk/src/types/VariableTypes.ts index a11b6dc7..c9566293 100644 --- a/packages/sdk/src/types/VariableTypes.ts +++ b/packages/sdk/src/types/VariableTypes.ts @@ -30,6 +30,7 @@ export enum VariableType { boolean = 'boolean', group = 'group', number = 'number', + date = 'date', } export interface Variable { @@ -78,10 +79,75 @@ export interface NumberVariable extends Variable { stepSize: number; } +export interface DateVariable extends Variable { + value?: string; + displayFormat: string; + startDate?: DateRestriction; + endDate?: DateRestriction; + excludedDays: Day[]; + locale: Locale; +} + export type LongTextVariable = ShortTextVariable; export type GroupVariable = Variable; +export type DateRestriction = RelativeDate | AbsoluteDate; + +export interface RelativeDate { + offset: number; + type: 'relative'; +} + +export interface AbsoluteDate { + value: string; + type: 'absolute'; +} + +export enum Day { + Monday = 'monday', + Tuesday = 'tuesday', + Wednesday = 'wednesday', + Thursday = 'thursday', + Friday = 'friday', + Saturday = 'saturday', + Sunday = 'sunday', +} + +export enum Locale { + en_US = 'en_US', + cs = 'cs', + da = 'da', + nl = 'nl', + fi = 'fi', + fr = 'fr', + de = 'de', + it = 'it', + no = 'no', + pl = 'pl', + pt_PT = 'pt_PT', + es_ES = 'es_ES', + sv = 'sv', +} + +export interface DateVariablePropertiesDeltaUpdate { + startDate?: { + value: DateRestriction | null; + }; + endDate?: { + value: DateRestriction | null; + }; + excludedDays?: { + value: Day[] | null; + }; + locale?: { + value: Locale; + }; + displayFormat?: { + value: string; + }; +} + export interface NumberVariablePropertiesDeltaUpdate { minValue?: { value: number | null;