@adaptabletools/adaptable-plugin-ipushpull-cjs 22.0.1 → 22.0.3

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": "@adaptabletools/adaptable-plugin-ipushpull-cjs",
3
- "version": "22.0.1",
3
+ "version": "22.0.3",
4
4
  "description": "",
5
5
  "homepage": "http://www.adaptabletools.com/",
6
6
  "author": {
@@ -10,12 +10,10 @@
10
10
  "main": "src/index.js",
11
11
  "typings": "src/index.d.ts",
12
12
  "dependencies": {
13
- "ipushpull-js": "^2.25.0",
14
13
  "react": "^18.0.0 || ^19.0.0",
15
14
  "react-redux": "^9.2.0",
16
15
  "redux": "^5.0.1",
17
16
  "styled-components": "^4.4.1",
18
- "tinycolor2": "^1.4.2",
19
17
  "tslib": "^2.8.1"
20
18
  },
21
19
  "peerDependencies": {}
@@ -1,8 +1,9 @@
1
1
  import { ApiBase } from "@adaptabletools/adaptable-cjs/src/Api/Implementation/ApiBase";
2
2
  import { IPushPullDomain, IPushPullReport, IPushPullSchedule } from "@adaptabletools/adaptable-cjs/src/AdaptableState/IPushPullState";
3
3
  import { IPushPullApi } from "@adaptabletools/adaptable-cjs/src/Api/IPushPullApi";
4
- import { IPushPullPluginOptions } from "@adaptabletools/adaptable-cjs/src/AdaptableOptions/IPushPullPluginOptions";
4
+ import { IPushPullPluginOptions } from './IPushPullPluginOptions';
5
5
  import { IAdaptable } from "@adaptabletools/adaptable-cjs/src/AdaptableInterfaces/IAdaptable";
6
+ import { IPushPullClient } from './ipushpull-client';
6
7
  export declare class IPushPullApiImpl extends ApiBase implements IPushPullApi {
7
8
  private ippInstance;
8
9
  private ippService;
@@ -14,8 +15,8 @@ export declare class IPushPullApiImpl extends ApiBase implements IPushPullApi {
14
15
  getIPushPullPassword(): string | undefined;
15
16
  getAutoLogin(): boolean;
16
17
  getCurrentLiveIPushPullReport(): IPushPullReport | undefined;
17
- setIPushPullInstance(ippInstance: any): void;
18
- getIPushPullInstance(): any;
18
+ setIPushPullInstance(ippInstance: IPushPullClient): void;
19
+ getIPushPullInstance(): IPushPullClient | null;
19
20
  sendSnapshot(iPushPullReport: IPushPullReport): void;
20
21
  startLiveData(iPushPullReport: IPushPullReport): void;
21
22
  stopLiveData(): void;
@@ -8,7 +8,7 @@ const IPushPullRedux = tslib_1.__importStar(require("./Redux/ActionReducers/IPus
8
8
  const ArrayExtensions_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/Utilities/Extensions/ArrayExtensions"));
9
9
  const Helper_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/Utilities/Helpers/Helper"));
10
10
  class IPushPullApiImpl extends ApiBase_1.ApiBase {
11
- ippInstance;
11
+ ippInstance = null;
12
12
  ippService = null;
13
13
  options;
14
14
  constructor(_adaptable, options) {
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Connection config for the ipushpull REST API.
3
+ *
4
+ * Only `api_key` and `api_secret` are required -- `api_url` defaults to the
5
+ * ipushpull test environment (`https://test.ipushpull.com/api/1.0`).
6
+ */
7
+ export interface IPushPullConfig {
8
+ /**
9
+ * Base URL for the ipushpull REST API
10
+ *
11
+ * @defaultValue 'https://test.ipushpull.com/api/1.0'
12
+ */
13
+ api_url?: string;
14
+ /** OAuth Client ID */
15
+ api_key: string;
16
+ /** OAuth Client Secret */
17
+ api_secret: string;
18
+ }
19
+ /**
20
+ * Options available in ipushpull plugin; allows users to collaborate and share data in powerful ways
21
+ */
22
+ export interface IPushPullPluginOptions {
23
+ /**
24
+ * The config required to run ipushpull; use your ipushpull credentials
25
+ */
26
+ ippConfig?: IPushPullConfig;
27
+ /**
28
+ * User's ipushpull user name (usually email address); if supplied, pre-populates the login screen's username textbox
29
+ */
30
+ username?: string;
31
+ /**
32
+ * The user's ipushpull password; if supplied, pre-populates the login screen's password textbox
33
+ */
34
+ password?: string;
35
+ /**
36
+ * How many miliseconds AdapTable should throttle when sending data updates to ipushpull
37
+ *
38
+ * @defaultValue 2000
39
+ */
40
+ throttleTime?: number;
41
+ /**
42
+ * Whether AdapTable should try log in to ipushpull automatically at start-up
43
+ *
44
+ * @defaultValue false
45
+ */
46
+ autoLogin?: boolean;
47
+ /**
48
+ * Whether AdapTable will include System Reports (e.g. 'All Data', 'Selected Cells' etc) in the ipushpull toolbar dropdown
49
+ *
50
+ * @defaultValue true
51
+ */
52
+ includeSystemReports?: boolean;
53
+ /**
54
+ * The color theme to use when styling data pushed to ipushpull pages
55
+ *
56
+ * @defaultValue derived from Adaptable's current theme (lightTheme or darkTheme)
57
+ */
58
+ cellStyles?: 'lightTheme' | 'darkTheme';
59
+ }
@@ -20,60 +20,58 @@ class PushPullModule extends AdaptableModuleBase_1.AdaptableModuleBase {
20
20
  setTimeout(() => {
21
21
  this.throttledRecomputeAndSendLiveDataEvent = (0, throttle_1.default)(() => this.sendNewLiveData(), this.getThrottleTimeFromState());
22
22
  }, 1000);
23
- if (this.getIPPApi().isIPushPullRunning()) {
24
- // if a piece of data has updated then update any live reports except cell or row selected where the data change is relevant
25
- // currently we DONT send deltas - we simply send everything to ipushpull every time a relevant change happens
26
- this.api.internalApi
27
- .getDataService()
28
- .on('CellDataChanged', (cellDataChangedInfo) => {
29
- const api = this.getIPPApi();
30
- const exportApi = this.api.exportApi;
31
- if (api.isIPushPullLiveDataRunning()) {
32
- let currentLiveIPushPullReport = api.getCurrentLiveIPushPullReport();
33
- if (currentLiveIPushPullReport &&
34
- currentLiveIPushPullReport.ReportName !== GeneralConstants_1.SELECTED_DATA_REPORT &&
35
- exportApi.internalApi.isDataChangeInReport(cellDataChangedInfo, this.getCurrentReport())) {
36
- this.throttledRecomputeAndSendLiveDataEvent();
37
- }
38
- }
39
- });
40
- // if the grid has refreshed then update all live reports
41
- this.adaptable._on('GridRefreshed', () => {
42
- if (this.getIPPApi().isIPushPullLiveDataRunning()) {
23
+ // if a piece of data has updated then update any live reports except cell or row selected where the data change is relevant
24
+ // currently we DONT send deltas - we simply send everything to ipushpull every time a relevant change happens
25
+ this.api.internalApi
26
+ .getDataService()
27
+ .on('CellDataChanged', (cellDataChangedInfo) => {
28
+ const api = this.getIPPApi();
29
+ const exportApi = this.api.exportApi;
30
+ if (api.isIPushPullLiveDataRunning()) {
31
+ let currentLiveIPushPullReport = api.getCurrentLiveIPushPullReport();
32
+ if (currentLiveIPushPullReport &&
33
+ currentLiveIPushPullReport.ReportName !== GeneralConstants_1.SELECTED_DATA_REPORT &&
34
+ exportApi.internalApi.isDataChangeInReport(cellDataChangedInfo, this.getCurrentReport())) {
43
35
  this.throttledRecomputeAndSendLiveDataEvent();
44
36
  }
45
- });
46
- // if the grid filters have changed then update any live reports except cell or row selected
47
- this.adaptable._on('AdapTableFiltersApplied', () => {
48
- // Rerun all reports except selected cells / rows when filter changes
49
- if (this.getIPPApi().isIPushPullLiveDataRunning()) {
50
- let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
51
- if (currentLiveIPushPullReport &&
52
- currentLiveIPushPullReport.ReportName !== GeneralConstants_1.SELECTED_DATA_REPORT) {
53
- this.throttledRecomputeAndSendLiveDataEvent();
54
- }
37
+ }
38
+ });
39
+ // if the grid has refreshed then update all live reports
40
+ this.adaptable._on('GridRefreshed', () => {
41
+ if (this.getIPPApi().isIPushPullLiveDataRunning()) {
42
+ this.throttledRecomputeAndSendLiveDataEvent();
43
+ }
44
+ });
45
+ // if the grid filters have changed then update any live reports except cell or row selected
46
+ this.adaptable._on('AdapTableFiltersApplied', () => {
47
+ // Rerun all reports except selected cells / rows when filter changes
48
+ if (this.getIPPApi().isIPushPullLiveDataRunning()) {
49
+ let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
50
+ if (currentLiveIPushPullReport &&
51
+ currentLiveIPushPullReport.ReportName !== GeneralConstants_1.SELECTED_DATA_REPORT) {
52
+ this.throttledRecomputeAndSendLiveDataEvent();
55
53
  }
56
- });
57
- // if grid selection has changed and the ipushpull Live report is 'Selected Cells' or 'Selected Rows' then send updated data
58
- this.api.eventApi.on('CellSelectionChanged', () => {
59
- if (this.getIPPApi().isIPushPullLiveDataRunning()) {
60
- let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
61
- if (currentLiveIPushPullReport &&
62
- currentLiveIPushPullReport.ReportName === GeneralConstants_1.SELECTED_DATA_REPORT) {
63
- this.throttledRecomputeAndSendLiveDataEvent();
64
- }
54
+ }
55
+ });
56
+ // if grid selection has changed and the ipushpull Live report is 'Selected Cells' or 'Selected Rows' then send updated data
57
+ this.api.eventApi.on('CellSelectionChanged', () => {
58
+ if (this.getIPPApi().isIPushPullLiveDataRunning()) {
59
+ let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
60
+ if (currentLiveIPushPullReport &&
61
+ currentLiveIPushPullReport.ReportName === GeneralConstants_1.SELECTED_DATA_REPORT) {
62
+ this.throttledRecomputeAndSendLiveDataEvent();
65
63
  }
66
- });
67
- this.api.eventApi.on('RowSelectionChanged', () => {
68
- if (this.getIPPApi().isIPushPullLiveDataRunning()) {
69
- let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
70
- if (currentLiveIPushPullReport &&
71
- currentLiveIPushPullReport.ReportName === GeneralConstants_1.SELECTED_DATA_REPORT) {
72
- this.throttledRecomputeAndSendLiveDataEvent();
73
- }
64
+ }
65
+ });
66
+ this.api.eventApi.on('RowSelectionChanged', () => {
67
+ if (this.getIPPApi().isIPushPullLiveDataRunning()) {
68
+ let currentLiveIPushPullReport = this.getIPPApi().getCurrentLiveIPushPullReport();
69
+ if (currentLiveIPushPullReport &&
70
+ currentLiveIPushPullReport.ReportName === GeneralConstants_1.SELECTED_DATA_REPORT) {
71
+ this.throttledRecomputeAndSendLiveDataEvent();
74
72
  }
75
- });
76
- }
73
+ }
74
+ });
77
75
  });
78
76
  }
79
77
  getViewAccessLevel() {
@@ -0,0 +1,39 @@
1
+ import { IAdaptable } from "@adaptabletools/adaptable-cjs/src/AdaptableInterfaces/IAdaptable";
2
+ import { IIPushPullService } from './Interface/IIPushPullService';
3
+ import { IPushPullDomain } from "@adaptabletools/adaptable-cjs/src/AdaptableState/InternalState";
4
+ import { IPushPullPluginOptions } from '../../IPushPullPluginOptions';
5
+ export declare enum ServiceStatus {
6
+ Unknown = "Unknown",
7
+ Disconnected = "Disconnected",
8
+ Connected = "Connected",
9
+ Error = "Error"
10
+ }
11
+ export declare class IPushPullService implements IIPushPullService {
12
+ adaptable: IAdaptable;
13
+ private client;
14
+ private status;
15
+ private cellStylesOption;
16
+ private pages;
17
+ private pageNameToId;
18
+ private folderNameToId;
19
+ constructor(adaptable: IAdaptable, cellStyles?: IPushPullPluginOptions['cellStyles']);
20
+ getIPushPullStatus(): ServiceStatus;
21
+ private getIPPApi;
22
+ /**
23
+ * Derives the IPushPull theme from Adaptable's current theme at call-time,
24
+ * respecting the 'os' theme by checking `prefers-color-scheme`.
25
+ */
26
+ private deriveDefaultTheme;
27
+ /**
28
+ * Returns the resolved IPushPull theme, honouring the `cellStyles` option.
29
+ * If `cellStyles` is a string, it's used directly.
30
+ * If not set, the theme is derived from Adaptable's current theme.
31
+ */
32
+ private getResolvedTheme;
33
+ login(login: string, password: string): Promise<any>;
34
+ getDomainPages(): Promise<IPushPullDomain[]>;
35
+ loadPage(folderIPP: string, pageIPP: string): Promise<void>;
36
+ unloadPage(page: string): void;
37
+ addNewPage(folderId: number, page: string): Promise<any>;
38
+ pushData(page: string, data: any[]): Promise<void>;
39
+ }
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IPushPullService = exports.ServiceStatus = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const StringExtensions_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/Utilities/Extensions/StringExtensions"));
6
+ const ipushpull_client_1 = require("../../ipushpull-client");
7
+ var ServiceStatus;
8
+ (function (ServiceStatus) {
9
+ ServiceStatus["Unknown"] = "Unknown";
10
+ ServiceStatus["Disconnected"] = "Disconnected";
11
+ ServiceStatus["Connected"] = "Connected";
12
+ ServiceStatus["Error"] = "Error";
13
+ })(ServiceStatus || (exports.ServiceStatus = ServiceStatus = {}));
14
+ class IPushPullService {
15
+ adaptable;
16
+ client = null;
17
+ status = ServiceStatus.Unknown;
18
+ cellStylesOption;
19
+ pages = new Map();
20
+ pageNameToId = new Map();
21
+ folderNameToId = new Map();
22
+ constructor(adaptable, cellStyles) {
23
+ this.adaptable = adaptable;
24
+ this.adaptable = adaptable;
25
+ this.cellStylesOption = cellStyles;
26
+ this.adaptable.api.eventApi.on('AdaptableReady', async () => {
27
+ this.getIPPApi().clearIPushPullInternalState();
28
+ this.getIPPApi().setIPushPullAvailableOff();
29
+ if (!this.client) {
30
+ let instance = this.getIPPApi().getIPushPullInstance();
31
+ if (instance) {
32
+ this.client = instance;
33
+ this.getIPPApi().setIPushPullAvailableOn();
34
+ let autoLogin = this.getIPPApi().getAutoLogin();
35
+ if (autoLogin) {
36
+ let userName = this.getIPPApi().getIPushPullUsername();
37
+ let password = this.getIPPApi().getIPushPullPassword();
38
+ if (StringExtensions_1.default.IsNotNullOrEmpty(userName) &&
39
+ StringExtensions_1.default.IsNotNullOrEmpty(password)) {
40
+ try {
41
+ this.getIPPApi().loginToIPushPull(userName, password);
42
+ }
43
+ catch (err) {
44
+ this.getIPPApi().setIPushPullRunningOff();
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ });
51
+ }
52
+ getIPushPullStatus() {
53
+ if (!this.client) {
54
+ return ServiceStatus.Error;
55
+ }
56
+ return this.status;
57
+ }
58
+ getIPPApi() {
59
+ return this.adaptable.api.pluginsApi.getipushpullPluginApi();
60
+ }
61
+ /**
62
+ * Derives the IPushPull theme from Adaptable's current theme at call-time,
63
+ * respecting the 'os' theme by checking `prefers-color-scheme`.
64
+ */
65
+ deriveDefaultTheme() {
66
+ const themeName = this.adaptable.api.themeApi.getCurrentTheme();
67
+ if (themeName === 'os') {
68
+ const preferred = this.adaptable.api.themeApi.internalApi.getDOMPreferredColorScheme();
69
+ return preferred === 'dark' ? 'darkTheme' : 'lightTheme';
70
+ }
71
+ const themeObj = this.adaptable.api.themeApi.getCurrentThemeObject();
72
+ if (themeObj?.Variant === 'dark') {
73
+ return 'darkTheme';
74
+ }
75
+ if (themeName === 'dark') {
76
+ return 'darkTheme';
77
+ }
78
+ return 'lightTheme';
79
+ }
80
+ /**
81
+ * Returns the resolved IPushPull theme, honouring the `cellStyles` option.
82
+ * If `cellStyles` is a string, it's used directly.
83
+ * If not set, the theme is derived from Adaptable's current theme.
84
+ */
85
+ getResolvedTheme() {
86
+ const defaultCellStyles = this.deriveDefaultTheme();
87
+ if (!this.cellStylesOption) {
88
+ return defaultCellStyles;
89
+ }
90
+ return this.cellStylesOption;
91
+ }
92
+ async login(login, password) {
93
+ if (!this.client) {
94
+ return Promise.reject('No ipushpull instance found!');
95
+ }
96
+ try {
97
+ const result = await this.client.login(login, password);
98
+ this.status = ServiceStatus.Connected;
99
+ this.adaptable.logger.success('Logged in to ipushpull.');
100
+ return result;
101
+ }
102
+ catch (err) {
103
+ this.status = ServiceStatus.Error;
104
+ const message = err.data ? err.data.error_description || err.message : err.message;
105
+ this.getIPPApi().setIPushPullLoginErrorMessage(message);
106
+ throw message;
107
+ }
108
+ }
109
+ async getDomainPages() {
110
+ if (!this.client) {
111
+ return Promise.reject('No ipushpull instance found.');
112
+ }
113
+ try {
114
+ const domains = await this.client.getDomainsAndPages();
115
+ this.adaptable.logger.success('Retrieved ipushpull folder and page info.');
116
+ this.folderNameToId.clear();
117
+ this.pageNameToId.clear();
118
+ const result = domains.map((domain) => {
119
+ this.folderNameToId.set(domain.name, domain.id);
120
+ const writablePages = domain.pages
121
+ .filter((page) => page.special_page_type == 0 && page.write_access)
122
+ .map((page) => {
123
+ this.pageNameToId.set(`${domain.name}/${page.name}`, page.id);
124
+ return page.name;
125
+ });
126
+ return {
127
+ Name: domain.name,
128
+ FolderId: domain.id,
129
+ Pages: writablePages,
130
+ };
131
+ });
132
+ return result;
133
+ }
134
+ catch (error) {
135
+ this.adaptable.logger.error('Failed to retrieve folders and pages from ipushpull.', error);
136
+ throw error.message ?? error;
137
+ }
138
+ }
139
+ async loadPage(folderIPP, pageIPP) {
140
+ if (!this.client) {
141
+ return Promise.reject('No ipushpull instance found.');
142
+ }
143
+ const folderId = this.folderNameToId.get(folderIPP);
144
+ const pageId = this.pageNameToId.get(`${folderIPP}/${pageIPP}`);
145
+ if (folderId == null || pageId == null) {
146
+ throw new Error(`Could not resolve IDs for folder "${folderIPP}" / page "${pageIPP}".`);
147
+ }
148
+ await this.client.getPageContent(folderId, pageId);
149
+ this.pages.set(pageIPP, { folderId, pageId });
150
+ this.adaptable.logger.info(`Page ready: "${pageIPP}".`);
151
+ }
152
+ unloadPage(page) {
153
+ if (this.pages.has(page)) {
154
+ this.pages.delete(page);
155
+ this.adaptable.logger.info(`Page unloaded: "${page}".`);
156
+ }
157
+ }
158
+ async addNewPage(folderId, page) {
159
+ if (!this.client) {
160
+ return Promise.reject('No ipushpull instance found.');
161
+ }
162
+ try {
163
+ await this.client.createPage(folderId, page);
164
+ let message = `Page "${page}" created successfully.`;
165
+ this.adaptable.api.alertApi.showAlertSuccess('ipushpull', message);
166
+ this.adaptable.api.internalApi.hidePopupScreen();
167
+ return this.getIPPApi().retrieveIPushPullDomainsFromIPushPull();
168
+ }
169
+ catch (err) {
170
+ this.adaptable.logger.error(`Failed to create page "${page}": ${err}`);
171
+ }
172
+ }
173
+ async pushData(page, data) {
174
+ const pageRef = this.pages.get(page);
175
+ if (!pageRef || !this.client) {
176
+ throw new Error(`Page "${page}" is not loaded or client is not available.`);
177
+ }
178
+ const themeStyles = (0, ipushpull_client_1.getThemeStyles)(this.getResolvedTheme());
179
+ const cellData = data.map((row, rowIndex) => row.map((cell) => {
180
+ let style;
181
+ if (rowIndex === 0) {
182
+ style = themeStyles.headerStyle;
183
+ }
184
+ else if (rowIndex % 2 === 1) {
185
+ style = themeStyles.rowStyle;
186
+ }
187
+ else {
188
+ style = themeStyles.altRowStyle;
189
+ }
190
+ return {
191
+ value: cell,
192
+ formatted_value: cell,
193
+ style,
194
+ };
195
+ }));
196
+ const payload = (0, ipushpull_client_1.buildPageContentPayload)(cellData);
197
+ try {
198
+ await this.client.updatePageContent(pageRef.folderId, pageRef.pageId, payload);
199
+ this.adaptable.logger.success(`Data pushed for ipushpull page "${page}".`);
200
+ }
201
+ catch (err) {
202
+ this.adaptable.logger.error(`Failed to push data for ipushpull page "${page}".`);
203
+ throw err;
204
+ }
205
+ }
206
+ }
207
+ exports.IPushPullService = IPushPullService;
@@ -1,6 +1,6 @@
1
- import { ServiceStatus } from '../PushPullService';
1
+ import { ServiceStatus } from '../IPushPullService';
2
2
  import { IPushPullDomain } from "@adaptabletools/adaptable-cjs/src/AdaptableState/InternalState";
3
- export interface IPushPullService {
3
+ export interface IIPushPullService {
4
4
  login(login: string, password: string): Promise<any>;
5
5
  getDomainPages(): Promise<IPushPullDomain[]>;
6
6
  loadPage(folderIPP: string, pageIPP: string): Promise<void>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,15 +8,14 @@ const PopupRedux = tslib_1.__importStar(require("@adaptabletools/adaptable-cjs/s
8
8
  const IPushPullRedux = tslib_1.__importStar(require("../Redux/ActionReducers/IPushPullRedux"));
9
9
  const StringExtensions_1 = require("@adaptabletools/adaptable-cjs/src/Utilities/Extensions/StringExtensions");
10
10
  const FormLayout_1 = tslib_1.__importStar(require("@adaptabletools/adaptable-cjs/src/components/FormLayout"));
11
- const Input_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/Input"));
11
+ const AdaptableInput_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/View/Components/AdaptableInput"));
12
12
  const SimpleButton_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/SimpleButton"));
13
- const FlexWithFooter_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/FlexWithFooter"));
14
13
  const PanelWithImage_1 = require("@adaptabletools/adaptable-cjs/src/View/Components/Panels/PanelWithImage");
15
14
  const PopupContext_1 = require("@adaptabletools/adaptable-cjs/src/View/Components/Popups/AdaptablePopup/PopupContext");
16
15
  const ErrorBox_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/ErrorBox"));
17
16
  const HelpBlock_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/HelpBlock"));
18
17
  const Flex_1 = require("@adaptabletools/adaptable-cjs/src/components/Flex");
19
- const Dropdown_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/Dropdown"));
18
+ const Select_1 = require("@adaptabletools/adaptable-cjs/src/components/Select");
20
19
  const GeneralConstants_1 = require("@adaptabletools/adaptable-cjs/src/Utilities/Constants/GeneralConstants");
21
20
  const ArrayExtensions_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/Utilities/Extensions/ArrayExtensions"));
22
21
  const IPushPullAddPageComponent = (props) => {
@@ -40,11 +39,11 @@ const IPushPullAddPageComponent = (props) => {
40
39
  setState({ ...state, Page: e.value });
41
40
  };
42
41
  const onFolderChanged = (folderName) => {
43
- if (StringExtensions_1.StringExtensions.IsNotNullOrEmpty(folderName) && folderName !== 'Select Folder') {
44
- let avaialablePages = props.IPushPullDomainsPages.find((f) => f.Name == folderName).Pages;
42
+ if (StringExtensions_1.StringExtensions.IsNotNullOrEmpty(folderName)) {
43
+ let availablePages = props.IPushPullDomainsPages.find((f) => f.Name == folderName)?.Pages ?? [];
45
44
  setState({
46
45
  Folder: folderName,
47
- AvailablePages: avaialablePages,
46
+ AvailablePages: availablePages,
48
47
  Page: GeneralConstants_1.EMPTY_STRING,
49
48
  ErrorMessage: GeneralConstants_1.EMPTY_STRING,
50
49
  });
@@ -64,29 +63,27 @@ const IPushPullAddPageComponent = (props) => {
64
63
  value: iPushPullDomain.Name,
65
64
  };
66
65
  });
67
- return (React.createElement(PanelWithImage_1.PanelWithImage, { header: "Add ipushpull Page", glyphicon: "newpage", variant: "primary", style: { height: '100%' } },
68
- React.createElement(FlexWithFooter_1.default, { as: "form", onSubmit: (e) => {
66
+ return (React.createElement(PanelWithImage_1.PanelWithImage, { header: "Add ipushpull Page", glyphicon: "newpage", variant: "primary" },
67
+ React.createElement("form", { onSubmit: (e) => {
69
68
  e.preventDefault();
70
69
  onSubmit();
71
- }, footerProps: {
72
- className: 'twa:text-4',
73
- }, footer: React.createElement(React.Fragment, null,
74
- React.createElement(SimpleButton_1.default, { tone: "neutral", variant: "text", tooltip: "Close", onClick: (e) => {
75
- e.stopPropagation();
76
- hidePopup();
77
- } }, "CLOSE"),
78
- React.createElement("div", { style: { flex: 1 } }),
79
- React.createElement(SimpleButton_1.default, { tone: "accent", variant: "raised", type: "submit", disabled: StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Folder) ||
80
- StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Page), icon: 'check' }, "Add Page")) },
70
+ } },
81
71
  React.createElement(Flex_1.Flex, { flexDirection: "column", className: "twa:p-2 twa:m-2" },
82
72
  React.createElement(HelpBlock_1.default, { className: "twa:mb-1" }, "Select a folder and then choose the name of the new ipushpull page it should contain."),
83
73
  React.createElement(FormLayout_1.default, { className: "twa:m-3" },
84
- React.createElement(FormLayout_1.FormRow, { label: "Folder:" },
85
- React.createElement(Dropdown_1.default, { disabled: availableFolders.length == 0, options: availableFolders, className: "ab-Popup__IPushPull__select twa:min-w-[50%] twa:mr-2", onChange: (folder) => onFolderChanged(folder), value: state.Folder ? state.Folder : null, placeholder: "Select Folder" })),
74
+ React.createElement(FormLayout_1.FormRow, { label: "Folder" },
75
+ React.createElement(Select_1.Select, { disabled: availableFolders.length == 0, options: availableFolders, className: "ab-Popup__IPushPull__select twa:min-w-[50%] twa:mr-2", onChange: (folder) => onFolderChanged(folder), value: state.Folder || undefined, placeholder: "Select Folder", isClearable: true })),
86
76
  React.createElement(FormLayout_1.FormRow, { label: "Page" },
87
- React.createElement(Input_1.default, { className: "twa:w-1/2", type: "text", placeholder: "Page Name", value: state.Page, onChange: onPageNameChange })),
77
+ React.createElement(AdaptableInput_1.default, { className: "twa:w-1/2", type: "text", placeholder: "Page Name", value: state.Page, disabled: StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Folder), onChange: onPageNameChange })),
88
78
  state.ErrorMessage ? (React.createElement(FormLayout_1.FormRow, { label: "" },
89
- React.createElement(ErrorBox_1.default, null, state.ErrorMessage))) : null)))));
79
+ React.createElement(ErrorBox_1.default, null, state.ErrorMessage))) : null)),
80
+ React.createElement(Flex_1.Flex, { className: "twa:p-2", justifyContent: "space-between" },
81
+ React.createElement(SimpleButton_1.default, { tone: "neutral", variant: "outlined", tooltip: "Close", onClick: (e) => {
82
+ e.stopPropagation();
83
+ hidePopup();
84
+ } }, "CLOSE"),
85
+ React.createElement(SimpleButton_1.default, { tone: "accent", variant: "raised", type: "submit", disabled: StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Folder) ||
86
+ StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Page), icon: 'check' }, "Add Page")))));
90
87
  };
91
88
  function mapStateToProps(state) {
92
89
  return {
@@ -9,9 +9,8 @@ const PopupRedux = tslib_1.__importStar(require("@adaptabletools/adaptable-cjs/s
9
9
  const IPushPullRedux = tslib_1.__importStar(require("../Redux/ActionReducers/IPushPullRedux"));
10
10
  const StringExtensions_1 = require("@adaptabletools/adaptable-cjs/src/Utilities/Extensions/StringExtensions");
11
11
  const FormLayout_1 = tslib_1.__importStar(require("@adaptabletools/adaptable-cjs/src/components/FormLayout"));
12
- const Input_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/Input"));
12
+ const AdaptableInput_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/View/Components/AdaptableInput"));
13
13
  const SimpleButton_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/SimpleButton"));
14
- const FlexWithFooter_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/FlexWithFooter"));
15
14
  const PanelWithImage_1 = require("@adaptabletools/adaptable-cjs/src/View/Components/Panels/PanelWithImage");
16
15
  const PopupContext_1 = require("@adaptabletools/adaptable-cjs/src/View/Components/Popups/AdaptablePopup/PopupContext");
17
16
  const ErrorBox_1 = tslib_1.__importDefault(require("@adaptabletools/adaptable-cjs/src/components/ErrorBox"));
@@ -36,28 +35,26 @@ const IPushPullLoginComponent = (props) => {
36
35
  const e = event.target;
37
36
  setState({ ...state, Password: e.value });
38
37
  };
39
- return (React.createElement(PanelWithImage_1.PanelWithImage, { header: "ipushpull Login Details", glyphicon: "login", variant: "primary", style: { height: '100%' } },
40
- React.createElement(FlexWithFooter_1.default, { as: "form", onSubmit: (e) => {
38
+ return (React.createElement(PanelWithImage_1.PanelWithImage, { header: "ipushpull Login Details", glyphicon: "login", variant: "primary" },
39
+ React.createElement("form", { onSubmit: (e) => {
41
40
  e.preventDefault();
42
41
  onSubmit();
43
- }, footerProps: {
44
- className: 'twa:text-4',
45
- }, footer: React.createElement(React.Fragment, null,
46
- React.createElement(SimpleButton_1.default, { tone: "neutral", variant: "text", tooltip: "Close", onClick: (e) => {
47
- e.stopPropagation();
48
- hidePopup();
49
- } }, "CLOSE"),
50
- React.createElement("div", { style: { flex: 1 } }),
51
- React.createElement(SimpleButton_1.default, { tone: "accent", variant: "raised", type: "submit", disabled: StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Password), icon: 'check' }, "Login")) },
42
+ } },
52
43
  React.createElement(Flex_1.Flex, { flexDirection: "column", className: "twa:p-2 twa:m-2" },
53
44
  React.createElement(HelpBlock_1.default, { className: "twa:mb-1" }, "Login to ipushpull using your login (email address) and password."),
54
45
  React.createElement(FormLayout_1.default, { className: "twa:m-3" },
55
- React.createElement(FormLayout_1.FormRow, { label: "ipushpull login:" },
56
- React.createElement(Input_1.default, { className: "twa:w-full", type: "email", placeholder: "Email address", value: state.Login, onChange: onLoginChange })),
57
- React.createElement(FormLayout_1.FormRow, { label: "ipushpull password:" },
58
- React.createElement(Input_1.default, { className: "twa:w-full", type: "password", placeholder: "Password", value: state.Password, onChange: onPasswordChange })),
46
+ React.createElement(FormLayout_1.FormRow, { label: "User" },
47
+ React.createElement(AdaptableInput_1.default, { className: "twa:w-full", type: "email", placeholder: "Email address", value: state.Login, onChange: onLoginChange })),
48
+ React.createElement(FormLayout_1.FormRow, { label: "Password" },
49
+ React.createElement(AdaptableInput_1.default, { className: "twa:w-full", type: "password", placeholder: "Password", value: state.Password, onChange: onPasswordChange })),
59
50
  props.pushpullLoginErrorMessage ? (React.createElement(FormLayout_1.FormRow, { label: "" },
60
- React.createElement(ErrorBox_1.default, null, props.pushpullLoginErrorMessage))) : null)))));
51
+ React.createElement(ErrorBox_1.default, null, props.pushpullLoginErrorMessage))) : null)),
52
+ React.createElement(Flex_1.Flex, { className: "twa:p-2", justifyContent: "space-between" },
53
+ React.createElement(SimpleButton_1.default, { tone: "neutral", variant: "outlined", tooltip: "Close", onClick: (e) => {
54
+ e.stopPropagation();
55
+ hidePopup();
56
+ } }, "CLOSE"),
57
+ React.createElement(SimpleButton_1.default, { tone: "accent", variant: "raised", type: "submit", disabled: StringExtensions_1.StringExtensions.IsNullOrEmpty(state.Password), icon: 'check' }, "Login")))));
61
58
  };
62
59
  function mapStateToProps(state) {
63
60
  return {