Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions src/apis/html-page-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,24 @@ class HTMLPageAPI {
return this.req.put(url, data, { headers: { 'Content-Type': 'application/json' } });
}

listRows(page_id, table_name, start, limit) {
listRows(page_id, table_name, start, limit, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/`;
const params = { page_id, table_name, start, limit };
if (preview_table_config && typeof preview_table_config === 'object') {
params.preview_table_config = JSON.stringify(preview_table_config);
}
return this.req.get(url, { params });
}

queryRows(page_id, table_name, conditions, start, limit, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/query/`;
const data = { page_id, table_name, conditions, start, limit };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this.req.post(url, data);
}

listCollaborators() {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-collaborators/`;
return this.req.get(url);
Expand All @@ -69,33 +81,48 @@ class HTMLPageAPI {
return this.req.post(url, data);
}

addRow(page_id, table_name, row_data) {
addRow(page_id, table_name, row_data, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/`;
const data = { page_id, table_name, row_data };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this.req.post(url, data);
}

addRows(page_id, table_name, rows_data) {
addRows(page_id, table_name, rows_data, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/batch/`;
const data = { page_id, table_name, rows_data };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this.req.post(url, data);
}

updateRow(page_id, table_name, row_id, row_data) {
updateRow(page_id, table_name, row_id, row_data, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/`;
const data = { page_id, table_name, row_id, row_data };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this._sendPut(url, data);
}

updateRows(page_id, table_name, rows_data) {
updateRows(page_id, table_name, rows_data, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/batch/`;
const data = { page_id, table_name, rows_data };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this._sendPut(url, data);
}

deleteRows(page_id, table_name, rows_ids) {
deleteRows(page_id, table_name, rows_ids, preview_table_config) {
const url = `${this.server}api/v2.1/universal-apps/${this.appUuid}/html-page-rows/`;
const data = { page_id, table_name, rows_ids };
if (preview_table_config && typeof preview_table_config === 'object') {
data.preview_table_config = preview_table_config;
}
return this._sendDelete(url, data);
}

Expand Down
1 change: 1 addition & 0 deletions src/iframe-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const POST_MESSAGE_REQUEST_TYPE = {
GET_ACCESS_TOKEN: 'get_access_token',
GET_APP_UUID: 'get_app_uuid',
GET_PAGE_ID: 'get_page_id',
GET_PREVIEW_TABLE_CONFIGS: 'get_preview_table_configs',
};

const WINDOW_EVENT_SOURCE_TYPE = {
Expand Down
37 changes: 31 additions & 6 deletions src/sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class HTMLPageSDK {
if (!this.options.pageId) {
this.options.pageId = await this.iframeAdapter.request(POST_MESSAGE_REQUEST_TYPE.GET_PAGE_ID);
}
if (this.options.pageId === 'ai_agent' && !Array.isArray(this.options.previewTableConfigs)) {
const previewTableConfigs = await this.iframeAdapter.request(POST_MESSAGE_REQUEST_TYPE.GET_PREVIEW_TABLE_CONFIGS);
this.options.previewTableConfigs = Array.isArray(previewTableConfigs) ? previewTableConfigs : [];
}
if (this.options.accountToken) {
// dev: try to get access-token via accountToken
const { server, accountToken, appUuid } = this.options;
Expand All @@ -35,7 +39,23 @@ export class HTMLPageSDK {
}

listRows({ tableName, start, limit }) {
return this.htmlPageAPI.listRows(this.options.pageId, tableName, start, limit);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.listRows(this.options.pageId, tableName, start, limit, previewTableConfig);
}

queryRows({ tableName, conditions, start, limit }) {
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.queryRows(this.options.pageId, tableName, conditions, start, limit, previewTableConfig);
}

_getPreviewTableConfig({ tableName }) {
if (this.options.pageId !== 'ai_agent' || !Array.isArray(this.options.previewTableConfigs)) return undefined;
const tableConfig = this.options.previewTableConfigs.find(config => tableName && config?.table_name === tableName);
if (!tableConfig) return undefined;
return {
table_id: tableConfig.table_id,
permissions: { ...(tableConfig.permissions || {}) },
};
}

listCollaborators() {
Expand All @@ -47,11 +67,13 @@ export class HTMLPageSDK {
}

addRow({ tableName, rowData }) {
return this.htmlPageAPI.addRow(this.options.pageId, tableName, rowData);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.addRow(this.options.pageId, tableName, rowData, previewTableConfig);
}

updateRow({ tableName, rowId, rowData }) {
return this.htmlPageAPI.updateRow(this.options.pageId, tableName, rowId, rowData);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.updateRow(this.options.pageId, tableName, rowId, rowData, previewTableConfig);
}

deleteRow({ tableName, rowId }) {
Expand All @@ -60,15 +82,18 @@ export class HTMLPageSDK {
}

batchAddRows({ tableName, rowsData }) {
return this.htmlPageAPI.addRows(this.options.pageId, tableName, rowsData);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.addRows(this.options.pageId, tableName, rowsData, previewTableConfig);
}

batchUpdateRows({ tableName, rowsData }) {
return this.htmlPageAPI.updateRows(this.options.pageId, tableName, rowsData);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.updateRows(this.options.pageId, tableName, rowsData, previewTableConfig);
}

batchDeleteRows({ tableName, rowsIds }) {
return this.htmlPageAPI.deleteRows(this.options.pageId, tableName, rowsIds);
const previewTableConfig = this._getPreviewTableConfig({ tableName });
return this.htmlPageAPI.deleteRows(this.options.pageId, tableName, rowsIds, previewTableConfig);
}

uploadFile({ file }) {
Expand Down
122 changes: 122 additions & 0 deletions tests/html-page-api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,62 @@ function createApi() {
return { api, get, post, put, del };
}

describe('HTMLPageAPI.queryRows', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('queryRows posts table name and conditions to the query endpoint', () => {
const { api, post } = createApi();

const response = { data: { metadata: [], results: [] } };
post.mockReturnValue(response);

const conditions = [{ columnName: 'Phone', value: '13800138000' }];
const result = api.queryRows('page-1', 'Orders', conditions, 0, 100);

expect(result).toEqual(response);
expect(post).toHaveBeenCalledWith(
'https://example.com/api/v2.1/universal-apps/app-uuid/html-page-rows/query/',
{
page_id: 'page-1',
table_name: 'Orders',
conditions,
start: 0,
limit: 100,
},
);
});

it('queryRows sends preview_table_config for ai_agent preview', () => {
const { api, post } = createApi();
const previewTableConfig = {
table_id: 'tbl-1',
permissions: {
query_rows_permission: {
enabled: true,
columns_keys: ['phone'],
query_columns: [{ column_key: 'phone', enable_fuzzy_query: true }],
},
},
};

api.queryRows('ai_agent', 'Orders', [{ columnName: 'Phone', value: '138' }], 0, 20, previewTableConfig);

expect(post).toHaveBeenCalledWith(
'https://example.com/api/v2.1/universal-apps/app-uuid/html-page-rows/query/',
{
page_id: 'ai_agent',
table_name: 'Orders',
conditions: [{ columnName: 'Phone', value: '138' }],
start: 0,
limit: 20,
preview_table_config: previewTableConfig,
},
);
});
});

describe('HTMLPageAPI.listRows', () => {
beforeEach(() => {
jest.clearAllMocks();
Expand Down Expand Up @@ -95,6 +151,26 @@ describe('HTMLPageAPI.listRows', () => {
},
);
});

it('listRows serializes preview_table_config', () => {
const { api, get } = createApi();
const previewTableConfig = { table_id: 'tbl-1', permissions: {} };

api.listRows('ai_agent', 'TableName', 0, 100, previewTableConfig);

expect(get).toHaveBeenCalledWith(
'https://example.com/api/v2.1/universal-apps/app-uuid/html-page-rows/',
{
params: {
page_id: 'ai_agent',
table_name: 'TableName',
start: 0,
limit: 100,
preview_table_config: JSON.stringify(previewTableConfig),
},
},
);
});
});

describe('HTMLPageAPI.listCollaborators', () => {
Expand Down Expand Up @@ -271,6 +347,52 @@ describe('HTMLPageAPI.deleteRows(s)', () => {
},
);
});

it('write APIs send preview_table_config', () => {
const { api, post, put, del } = createApi();
const previewTableConfig = { table_id: 'tbl-1', permissions: {} };

api.addRow('ai_agent', 'TableName', { Name: 'A' }, previewTableConfig);
api.addRows('ai_agent', 'TableName', [{ Name: 'B' }], previewTableConfig);
api.updateRow('ai_agent', 'TableName', 'row-1', { Name: 'C' }, previewTableConfig);
api.updateRows('ai_agent', 'TableName', [{ row_id: 'row-1', row: { Name: 'D' } }], previewTableConfig);
api.deleteRows('ai_agent', 'TableName', ['row-1'], previewTableConfig);

expect(post).toHaveBeenNthCalledWith(1, expect.any(String), {
page_id: 'ai_agent',
table_name: 'TableName',
row_data: { Name: 'A' },
preview_table_config: previewTableConfig,
});
expect(post).toHaveBeenNthCalledWith(2, expect.any(String), {
page_id: 'ai_agent',
table_name: 'TableName',
rows_data: [{ Name: 'B' }],
preview_table_config: previewTableConfig,
});
expect(put).toHaveBeenNthCalledWith(1, expect.any(String), {
page_id: 'ai_agent',
table_name: 'TableName',
row_id: 'row-1',
row_data: { Name: 'C' },
preview_table_config: previewTableConfig,
}, expect.any(Object));
expect(put).toHaveBeenNthCalledWith(2, expect.any(String), {
page_id: 'ai_agent',
table_name: 'TableName',
rows_data: [{ row_id: 'row-1', row: { Name: 'D' } }],
preview_table_config: previewTableConfig,
}, expect.any(Object));
expect(del).toHaveBeenCalledWith(expect.any(String), {
headers: { 'Content-Type': 'application/json' },
data: {
page_id: 'ai_agent',
table_name: 'TableName',
rows_ids: ['row-1'],
preview_table_config: previewTableConfig,
},
});
});
});

describe('HTMLPageAPI.upload', () => {
Expand Down
18 changes: 18 additions & 0 deletions tests/sdk-init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jest.mock('../src/iframe-adapter', () => ({
GET_ACCESS_TOKEN: 'get_access_token',
GET_APP_UUID: 'get_app_uuid',
GET_PAGE_ID: 'get_page_id',
GET_PREVIEW_TABLE_CONFIGS: 'get_preview_table_configs',
},
}));

Expand Down Expand Up @@ -78,4 +79,21 @@ describe('HTMLPageSDK.init', () => {
expect(sdk.options.pageId).toBe('page-1');
expect(sdk.options.accountToken).toBe('account-token');
});

it('loads table permission configs for ai_agent preview', async () => {
const previewTableConfigs = [{ table_id: 'REW7', permissions: {} }];
mockRequest
.mockResolvedValueOnce('https://example.com')
.mockResolvedValueOnce('app-uuid')
.mockResolvedValueOnce('ai_agent')
.mockResolvedValueOnce(previewTableConfigs)
.mockResolvedValueOnce('access-token');

const sdk = new HTMLPageSDK();
await sdk.init();

expect(mockRequest).toHaveBeenNthCalledWith(4, 'get_preview_table_configs');
expect(mockRequest).toHaveBeenNthCalledWith(5, 'get_access_token');
expect(sdk.options.previewTableConfigs).toEqual(previewTableConfigs);
});
});
Loading
Loading