Skip to content

Commit

Permalink
Merge pull request #99 from amplience/feature/CRNTT-sdk-changes
Browse files Browse the repository at this point in the history
Feature/crntt sdk changes
  • Loading branch information
pixelscript authored May 15, 2024
2 parents 1eb8f36 + 700dadc commit 23d73cf
Show file tree
Hide file tree
Showing 23 changed files with 410 additions and 68 deletions.
70 changes: 25 additions & 45 deletions src/lib/components/ApplicationNavigator.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,50 @@
import { LOCATION_HREF } from '../constants/LocationHref';
import { APPLICATION_NAVIGATOR } from '../constants/Errors';
interface ContentItem {
id?: string;
}

interface Event {
id?: string;
}

interface Edition {
id?: string;
eventId?: string;
}

export interface OpenOptions {
returnHref: boolean;
}
import { Event } from '../models/Event';
import { Edition } from '../models/Edition';
import { BaseNavigator } from './BaseNavigator';
import { OpenOptions } from '../constants/Navigation';
import { ContentItemModel } from '../models/ContentItemModel';

export class ApplicationNavigator {
constructor(private readonly locationHref: string, private window: Window) {}
private navigationService: BaseNavigator;

constructor(locationHref: string, window: Window) {
this.navigationService = new BaseNavigator(locationHref, window);
}

openEventsCalendar(options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/planning/events/calendar`, options);
return this.navigationService.navigate(`/planning/events/calendar`, options);
}

openEventsTimeline(options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/planning/events/timeline`, options);
return this.navigationService.navigate(`/planning/events/timeline`, options);
}

openEventsList(options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/planning/events/list`, options);
return this.navigationService.navigate(`/planning/events/list`, options);
}

openEvent(event: Event, options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/planning/event/${event.id}`, options);
return this.navigationService.navigate(`/planning/event/${event.id}`, options);
}

openEdition(edition: Edition, options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(
`${this.getBaseHref()}/planning/edition/${edition.eventId}/${edition.id}/`,
return this.navigationService.navigate(
`/planning/edition/${edition.eventId}/${edition.id}/`,
options
);
}

openContentLibrary(options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/authoring/content-items`, options);
}

openContentItem(id: ContentItem, options: Partial<OpenOptions> = {}): undefined | string {
return this.processHref(`${this.getBaseHref()}/authoring/content-item/edit/${id.id}`, options);
}

private processHref(href: string, options: Partial<OpenOptions>): string | undefined {
if (options.returnHref) {
return href;
}
this.window.parent.location.href = href;
return this.navigationService.navigate(`/authoring/content-items`, options);
}

private getBaseHref() {
if (this.locationHref.indexOf(LOCATION_HREF.HASH_BANG) === -1) {
throw new Error(APPLICATION_NAVIGATOR.MUST_INCLUDE_HASH_BANG);
}

const [baseUrl, hash] = this.locationHref.split(LOCATION_HREF.HASH_BANG);
const hubName = hash.split('/')[1];
return `${baseUrl}${LOCATION_HREF.HASH_BANG}/${hubName}`;
openContentItem(
contentItem: Partial<ContentItemModel>,
options: Partial<OpenOptions> = {}
): undefined | string {
return this.navigationService.navigate(
`/authoring/content-item/edit/${contentItem.id}`,
options
);
}
}
31 changes: 31 additions & 0 deletions src/lib/components/BaseNavigator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { OpenOptions } from '../constants/Navigation';
import { LOCATION_HREF } from '../constants/LocationHref';
import { APPLICATION_NAVIGATOR } from '../constants/Errors';

export class BaseNavigator {
constructor(public readonly locationHref: string, public window: Window) {}

navigate(templatedUri: string, options: Partial<OpenOptions> = {}) {
const base = this.getBaseHref();

return this.processHref(`${base}${templatedUri}`, options);
}

private processHref(href: string, options: Partial<OpenOptions> = {}): string | undefined {
if (options.returnHref) {
return href;
}
this.window.parent.location.href = href;
}

private getBaseHref() {
if (this.locationHref.indexOf(LOCATION_HREF.HASH_BANG) === -1) {
throw new Error(APPLICATION_NAVIGATOR.MUST_INCLUDE_HASH_BANG);
}

const [baseUrl, hash] = this.locationHref.split(LOCATION_HREF.HASH_BANG);
const hubName = hash.split('/')[1];

return `${baseUrl}${LOCATION_HREF.HASH_BANG}/${hubName}`;
}
}
1 change: 0 additions & 1 deletion src/lib/components/ContentEditorForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ClientConnection } from 'message-event-channel';
import { ContentEditorForm } from './ContentEditorForm';
import { CONTENT_EDITOR_FORM, FORM } from '../constants/Events';
import { FORM as ERRORS } from '../constants/Errors';
import { request } from 'http';
import { ErrorReport } from '../models/ErrorReport';

describe('ContentEditorForm', () => {
Expand Down
38 changes: 38 additions & 0 deletions src/lib/components/ContentEditorNavigator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ClientConnection } from 'message-event-channel';
import { ContentEditorApplicationNavigator } from './ContentEditorNavigator';

describe('ContentEditorNavigator', () => {
let navigator: ContentEditorApplicationNavigator;
let onSpy: jest.SpyInstance;
let connection: ClientConnection;
let localWindow: Window;

beforeEach(() => {
connection = new ClientConnection();
onSpy = jest.spyOn(connection, 'on');
localWindow = {
parent: {
location: {
href: '',
},
},
} as Window;
navigator = new ContentEditorApplicationNavigator(connection);
});

describe('editContentItem', () => {
it('should request from connection', async () => {
jest.spyOn(connection, 'request').mockReturnValue(Promise.resolve());

await navigator.editContentItem(
'3fc3a416-574f-48df-aa29-d96fdbdb6279',
'https://simple-text.com'
);

expect(connection.request).toBeCalledWith('navigate-to-nested', {
uri: 'https://simple-text.com',
id: '3fc3a416-574f-48df-aa29-d96fdbdb6279',
});
});
});
});
21 changes: 21 additions & 0 deletions src/lib/components/ContentEditorNavigator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ClientConnection } from 'message-event-channel';
import { CONTENT_ITEM_NAVIGATOR } from '../constants/Events';

export class ContentEditorApplicationNavigator {
constructor(private readonly connection: ClientConnection) {}

/**
*
* @param contentItemId - content item you're wanting to navigate to
* @param contentTypeUri - content type uri from a schema id
*
* Used to navigate to nested content item
*
*/
editContentItem(contentItemId: string, contentTypeUri: string) {
return this.connection.request<void>(CONTENT_ITEM_NAVIGATOR.NAVIGATE_TO_NESTED, {
uri: contentTypeUri,
id: contentItemId,
});
}
}
49 changes: 49 additions & 0 deletions src/lib/components/ContentType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { CONTENT_TYPES } from '../constants/Events';
import { ClientConnection } from 'message-event-channel';
import { ContentTypeModel } from '../models/ContentType';

export class ContentTypes {
constructor(private connection: ClientConnection) {}

/**
*
* @param uri schema id / content type uri
*
* Used to get content type settings for a schema
*
* @returns [[Promise<ContentTypeModel>]]
*
* ### Example
*
* ```typescript
* const contentType = sdk.contentTypes.getByUri('https://example-schema.com/blog.json')
*
* console.log(contentType)
* ```
* @returns
*/
async getByUri(uri: string): Promise<ContentTypeModel> {
return this.connection.request(CONTENT_TYPES.GET_BY_URI, { uri });
}

/**
*
* @param uri list of schema id / content type uri
*
* Used to get content type settings for a schema
*
* @returns [[Promise<ContentTypeModel[]>]]
*
* ### Example
*
* ```typescript
* const contentTypes = sdk.contentTypes.getByUri(['https://example-schema.com/blog.json', 'https://example-schema.com/user.json'])
*
* console.log(contentTypes)
* ```
* @returns
*/
async getByUris(uris: string[]): Promise<ContentTypeModel[]> {
return this.connection.request(CONTENT_TYPES.GET_BY_URIS, { uris });
}
}
47 changes: 34 additions & 13 deletions src/lib/components/HttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,25 @@ import { ClientConnection } from 'message-event-channel';
/**
* @hidden
*/
export interface HttpResponse {
export interface HttpResponse<Resource = string | Record<string, unknown>> {
status: number;
data: string | Record<string, unknown>;
data: Resource;
}

/**
* @hidden
*/
export interface HttpError {
code: string;
level: string;
message: string;
}

/**
* @hidden
*/
export interface HttpErrors {
errors: HttpError[];
}

/**
Expand Down Expand Up @@ -64,28 +80,33 @@ export class HttpClient {

constructor(private connection: ClientConnection) {}

public async request(config: HttpRequest): Promise<HttpResponse> {
public async request<Resource = string | Record<string, unknown>>(
config: HttpRequest
): Promise<HttpResponse<Resource | HttpErrors>> {
try {
const response = await this.connection.request<HttpResponse>('dc-management-sdk-js:request', {
data: config.data,
method: config.method,
headers: config.headers,
url: config.url,
});
const response = await this.connection.request<HttpResponse<Resource>>(
'dc-management-sdk-js:request',
{
data: config.data,
method: config.method,
headers: config.headers,
url: config.url,
}
);

return {
data: response.data,
status: response.status,
};
} catch (error) {
} catch (error: any) {
if (error) {
return {
data: error.data,
status: error.status,
data: error?.data,
status: error?.status,
};
}

return this.DEFAULT_ERROR;
return this.DEFAULT_ERROR as HttpResponse<HttpErrors>;
}
}
}
48 changes: 48 additions & 0 deletions src/lib/components/MediaLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,54 @@ export class MediaLink {
* @param connection message-event-channel connection
*/
constructor(private connection: ClientConnection) {}

/**
* This method will trigger opening the media browser. It returns a promise that will resolve to the chosen Image or Video Link.
*
* Example of fetching media from DC
* ```typescript
* try {
* // open browser and waits for media browser
* // returns object that should be saved to the model
* const video = await sdk.mediaLink.get()
*
* } catch (e) {
* // no media returned
* }
* ```
*/
async get(): Promise<MediaImageLink | MediaVideoLink> {
return this.connection.request(MEDIA_LINK.GET, null, {
timeout: false,
});
}

/**
* This method will trigger opening the media overlay. It returns a promise that will resolve to the chosen Image and Video Links.
*
* Example of fetching an media from DC
* ```typescript
* try {
* // open browser and waits for media selection
* // returns object that should be saved to the model
* const media = await sdk.mediaLink.getMultiple({ max: 10 })
*
* } catch (e) {
* // no media returned
* }
* ```
*/
async getMultiple(
{ max }: MediaOptions = { max: null }
): Promise<Array<MediaImageLink | MediaImageLink>> {
return this.connection.request(
MEDIA_LINK.GET,
{ max },
{
timeout: false,
}
);
}
/**
* This method will trigger an image browser. It returns a promise that will resolve to the chosen Image Link.
*
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/Users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export class Users {

private async getAuthUsers(): Promise<AuthUser[]> {
try {
const response: HttpResponse = await this.httpClient.request({
const response = await this.httpClient.request({
url: USERS_URL,
method: HttpMethod.GET,
});
Expand All @@ -97,8 +97,8 @@ export class Users {
}

return (response?.data as Record<'data', AuthUser[]>)?.data || [];
} catch (error) {
throw new Error(`Unable to get users: ${error.message}`);
} catch (error: any) {
throw new Error(`Unable to get users: ${error?.message}`);
}
}

Expand Down
Loading

0 comments on commit 23d73cf

Please sign in to comment.