@oanda/labs-instruments-table-widget 1.0.26 → 1.0.28

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/dist/main/InstrumentsTableWidget/InstrumentsTableWidget.js +9 -7
  3. package/dist/main/InstrumentsTableWidget/InstrumentsTableWidget.js.map +1 -1
  4. package/dist/main/InstrumentsTableWidget/Main.js +27 -10
  5. package/dist/main/InstrumentsTableWidget/Main.js.map +1 -1
  6. package/dist/main/InstrumentsTableWidget/config.js +77 -14
  7. package/dist/main/InstrumentsTableWidget/config.js.map +1 -1
  8. package/dist/main/InstrumentsTableWidget/types.js.map +1 -1
  9. package/dist/main/gql/resolveInstrumentsWithFilters.js +5 -0
  10. package/dist/main/gql/resolveInstrumentsWithFilters.js.map +1 -1
  11. package/dist/main/gql/types/gql.js +1 -1
  12. package/dist/main/gql/types/gql.js.map +1 -1
  13. package/dist/main/gql/types/graphql.js +115 -1
  14. package/dist/main/gql/types/graphql.js.map +1 -1
  15. package/dist/main/translations/sources/en.json +8 -2
  16. package/dist/module/InstrumentsTableWidget/InstrumentsTableWidget.js +10 -8
  17. package/dist/module/InstrumentsTableWidget/InstrumentsTableWidget.js.map +1 -1
  18. package/dist/module/InstrumentsTableWidget/Main.js +29 -12
  19. package/dist/module/InstrumentsTableWidget/Main.js.map +1 -1
  20. package/dist/module/InstrumentsTableWidget/config.js +78 -14
  21. package/dist/module/InstrumentsTableWidget/config.js.map +1 -1
  22. package/dist/module/InstrumentsTableWidget/types.js.map +1 -1
  23. package/dist/module/gql/resolveInstrumentsWithFilters.js +5 -0
  24. package/dist/module/gql/resolveInstrumentsWithFilters.js.map +1 -1
  25. package/dist/module/gql/types/gql.js +1 -1
  26. package/dist/module/gql/types/gql.js.map +1 -1
  27. package/dist/module/gql/types/graphql.js +114 -0
  28. package/dist/module/gql/types/graphql.js.map +1 -1
  29. package/dist/module/translations/sources/en.json +8 -2
  30. package/dist/types/InstrumentsTableWidget/Main.d.ts +1 -1
  31. package/dist/types/InstrumentsTableWidget/config.d.ts +9 -9
  32. package/dist/types/InstrumentsTableWidget/types.d.ts +1 -0
  33. package/dist/types/gql/types/gql.d.ts +4 -2
  34. package/dist/types/gql/types/graphql.d.ts +22 -2
  35. package/package.json +3 -3
  36. package/src/InstrumentsTableWidget/InstrumentsTableWidget.tsx +24 -5
  37. package/src/InstrumentsTableWidget/Main.tsx +51 -7
  38. package/src/InstrumentsTableWidget/config.ts +84 -33
  39. package/src/InstrumentsTableWidget/types.ts +1 -0
  40. package/src/gql/resolveInstrumentsWithFilters.ts +5 -0
  41. package/src/gql/types/gql.ts +3 -3
  42. package/src/gql/types/graphql.ts +103 -2
  43. package/src/translations/sources/en.json +8 -2
  44. package/test/Main.test.tsx +23 -0
  45. package/test/mocks.ts +53 -1
@@ -3,6 +3,7 @@
3
3
  "asset_class": "Asset class",
4
4
  "bond": "Bond",
5
5
  "buy": "Buy",
6
+ "close_only": "Close only",
6
7
  "commodity": "Commodity",
7
8
  "crypto": "Crypto",
8
9
  "currency": "Currency",
@@ -12,12 +13,17 @@
12
13
  "index": "Index",
13
14
  "instrument": "Instrument",
14
15
  "instrument_name": "Instrument name",
16
+ "long_only": "Long only",
15
17
  "no_matching_results": "No matching results",
16
18
  "pagination_entries_range": "{{firstItemOnPage}}-{{lastItemOnPage}} of {{itemCount}} entries",
17
19
  "search": "Search",
18
20
  "sell": "Sell",
19
21
  "share_cfds": "Share CFDs",
22
+ "short_only": "Short only",
20
23
  "spread": "Spread",
21
- "today_high": "Today High",
22
- "today_low": "Today Low"
24
+ "symbol": "Symbol",
25
+ "today_high": "Today high",
26
+ "today_low": "Today low",
27
+ "trade_mode": "Trade mode",
28
+ "last_updated": "Last updated"
23
29
  }
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import type { MainProps } from './types';
3
- declare const Main: ({ instruments, division, assetClasses, columns, isAssetClassFilterEnabled, isInstrumentSearchEnabled, recordsPerPage, dataSource, }: MainProps) => React.JSX.Element;
3
+ declare const Main: ({ instruments, division, assetClasses, columns, isAssetClassFilterEnabled, isInstrumentSearchEnabled, recordsPerPage, dataSource, isLiveRatesDisabled, }: MainProps) => React.JSX.Element;
4
4
  export { Main };
@@ -1,11 +1,11 @@
1
- import type { HeaderColumns } from '@oanda/labs-widget-common';
2
- import { DataRecordType } from '@oanda/labs-widget-common';
1
+ import type { HeaderConfigType } from '@oanda/labs-widget-common';
2
+ import { TradeMode } from '../gql/types/graphql';
3
3
  import type { AssetClassLabels } from './components/Filters/types';
4
- type HeaderRecordType = DataRecordType.INSTRUMENT | DataRecordType.SELL | DataRecordType.BUY | DataRecordType.DAILY_CHANGE | DataRecordType.SPREAD | DataRecordType.HIGH | DataRecordType.LOW;
5
- declare const headerConfig: Record<HeaderRecordType, {
6
- displayName: string;
7
- additionalStyles: string;
8
- }>;
4
+ declare const tradeModeLabels: Record<TradeMode.TradeLongonly | TradeMode.TradeShortonly | TradeMode.TradeCloseonly, string>;
5
+ declare const headerConfigs: {
6
+ normal: HeaderConfigType;
7
+ longInstruments: HeaderConfigType;
8
+ mobile: HeaderConfigType;
9
+ };
9
10
  declare const assetClassLabels: Record<AssetClassLabels, string>;
10
- declare const getHeaderConfig: (activeColumns: DataRecordType[]) => HeaderColumns[];
11
- export { assetClassLabels, getHeaderConfig, headerConfig };
11
+ export { assetClassLabels, headerConfigs, tradeModeLabels };
@@ -25,4 +25,5 @@ export interface MainProps {
25
25
  isInstrumentSearchEnabled?: boolean;
26
26
  recordsPerPage?: number;
27
27
  dataSource: InstrumentDataSource;
28
+ isLiveRatesDisabled?: boolean;
28
29
  }
@@ -11,14 +11,16 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
11
11
  * Therefore it is highly recommended to use the babel or swc plugin for production.
12
12
  */
13
13
  declare const documents: {
14
- '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n': DocumentNode<types.ResolveInstrumentsWithFiltersQuery, types.Exact<{
14
+ '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n': DocumentNode<types.ResolveInstrumentsWithFiltersQuery, types.Exact<{
15
15
  division: types.Division;
16
16
  assetClass?: types.InputMaybe<Array<types.InputMaybe<types.AssetClassName>> | types.InputMaybe<types.AssetClassName>>;
17
17
  dataSource?: types.InputMaybe<types.InstrumentDataSource>;
18
18
  instruments?: types.InputMaybe<Array<types.InputMaybe<types.Scalars["String"]["input"]>> | types.InputMaybe<types.Scalars["String"]["input"]>>;
19
19
  searchPattern?: types.InputMaybe<types.Scalars["String"]["input"]>;
20
+ tradeModes?: types.InputMaybe<Array<types.InputMaybe<types.TradeMode>> | types.InputMaybe<types.TradeMode>>;
20
21
  count?: types.InputMaybe<types.Scalars["Int"]["input"]>;
21
22
  offset?: types.InputMaybe<types.Scalars["Int"]["input"]>;
23
+ withTradingModes: types.Scalars["Boolean"]["input"];
22
24
  }>>;
23
25
  };
24
26
  /**
@@ -37,6 +39,6 @@ export declare function graphql(source: string): unknown;
37
39
  /**
38
40
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
39
41
  */
40
- export declare function graphql(source: '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n'): (typeof documents)['\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n'];
42
+ export declare function graphql(source: '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n'): (typeof documents)['\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n'];
41
43
  export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
42
44
  export {};
@@ -134,6 +134,12 @@ export declare enum Division {
134
134
  Opt = "OPT",
135
135
  Otms = "OTMS"
136
136
  }
137
+ export type ExtendedInstrument = {
138
+ __typename?: 'ExtendedInstrument';
139
+ displayName: Scalars['String']['output'];
140
+ name: Scalars['String']['output'];
141
+ tradeMode: TradeMode;
142
+ };
137
143
  export type Heatmap = {
138
144
  __typename?: 'Heatmap';
139
145
  instrument: Instrument;
@@ -155,8 +161,9 @@ export declare enum InstrumentDataSource {
155
161
  }
156
162
  export type InstrumentTableResult = {
157
163
  __typename?: 'InstrumentTableResult';
158
- instruments: Array<Instrument>;
164
+ instruments: Array<ExtendedInstrument>;
159
165
  totalCount: Scalars['Int']['output'];
166
+ updatedAt: Scalars['String']['output'];
160
167
  };
161
168
  export type Matrix = {
162
169
  __typename?: 'Matrix';
@@ -243,6 +250,7 @@ export type QueryResolveInstrumentsWithFiltersArgs = {
243
250
  instruments?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
244
251
  offset?: InputMaybe<Scalars['Int']['input']>;
245
252
  searchPattern?: InputMaybe<Scalars['String']['input']>;
253
+ tradeModes?: InputMaybe<Array<InputMaybe<TradeMode>>>;
246
254
  };
247
255
  export type QuerySentimentArgs = {
248
256
  division?: InputMaybe<Division>;
@@ -337,6 +345,14 @@ export declare enum TopicalSort {
337
345
  Popular = "POPULAR",
338
346
  Volatile = "VOLATILE"
339
347
  }
348
+ export declare enum TradeMode {
349
+ TradeCloseonly = "TRADE_CLOSEONLY",
350
+ TradeDisabled = "TRADE_DISABLED",
351
+ TradeFull = "TRADE_FULL",
352
+ TradeLongonly = "TRADE_LONGONLY",
353
+ TradeShortonly = "TRADE_SHORTONLY",
354
+ TradeUndefined = "TRADE_UNDEFINED"
355
+ }
340
356
  export declare enum ValueAtRiskBars {
341
357
  C100 = "C100",
342
358
  C200 = "C200",
@@ -400,18 +416,22 @@ export type ResolveInstrumentsWithFiltersQueryVariables = Exact<{
400
416
  dataSource?: InputMaybe<InstrumentDataSource>;
401
417
  instruments?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>> | InputMaybe<Scalars['String']['input']>>;
402
418
  searchPattern?: InputMaybe<Scalars['String']['input']>;
419
+ tradeModes?: InputMaybe<Array<InputMaybe<TradeMode>> | InputMaybe<TradeMode>>;
403
420
  count?: InputMaybe<Scalars['Int']['input']>;
404
421
  offset?: InputMaybe<Scalars['Int']['input']>;
422
+ withTradingModes: Scalars['Boolean']['input'];
405
423
  }>;
406
424
  export type ResolveInstrumentsWithFiltersQuery = {
407
425
  __typename?: 'Query';
408
426
  resolveInstrumentsWithFilters?: {
409
427
  __typename?: 'InstrumentTableResult';
410
428
  totalCount: number;
429
+ updatedAt?: string;
411
430
  instruments: Array<{
412
- __typename?: 'Instrument';
431
+ __typename?: 'ExtendedInstrument';
413
432
  name: string;
414
433
  displayName: string;
434
+ tradeMode?: TradeMode;
415
435
  }>;
416
436
  } | null;
417
437
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oanda/labs-instruments-table-widget",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Labs Instruments Table Widget",
5
5
  "main": "dist/main/index.js",
6
6
  "module": "dist/module/index.js",
@@ -12,7 +12,7 @@
12
12
  "author": "OANDA",
13
13
  "license": "UNLICENSED",
14
14
  "dependencies": {
15
- "@oanda/labs-widget-common": "^1.0.206",
15
+ "@oanda/labs-widget-common": "^1.0.208",
16
16
  "@oanda/mono-i18n": "10.0.1",
17
17
  "graphql": "16.8.1"
18
18
  },
@@ -20,5 +20,5 @@
20
20
  "@graphql-codegen/cli": "5.0.0",
21
21
  "@graphql-codegen/client-preset": "4.1.0"
22
22
  },
23
- "gitHead": "8e9089b3a4cc94275dd2223e7fed7aae070fe454"
23
+ "gitHead": "5ac438aecc3ec1cc9e02e6c68e7cf3bf1e6eadd4"
24
24
  }
@@ -1,5 +1,9 @@
1
1
  import { ApolloClient, InMemoryCache } from '@apollo/client';
2
- import { WidgetProvider, WidgetWrapper } from '@oanda/labs-widget-common';
2
+ import {
3
+ DataRecordType,
4
+ WidgetProvider,
5
+ WidgetWrapper,
6
+ } from '@oanda/labs-widget-common';
3
7
  import React from 'react';
4
8
 
5
9
  import { translations } from '../translations';
@@ -35,13 +39,27 @@ const InstrumentsTableWidget = ({
35
39
  dataSource
36
40
  );
37
41
 
42
+ const liveRates =
43
+ !columns ||
44
+ columns?.some(
45
+ (column) =>
46
+ column === DataRecordType.BUY ||
47
+ column === DataRecordType.SELL ||
48
+ column === DataRecordType.DAILY_CHANGE ||
49
+ column === DataRecordType.SPREAD ||
50
+ column === DataRecordType.HIGH ||
51
+ column === DataRecordType.LOW
52
+ )
53
+ ? {
54
+ url: liveRatesUrl,
55
+ options: { divisionCode, dataSource },
56
+ }
57
+ : undefined;
58
+
38
59
  return (
39
60
  <WidgetProvider
40
61
  client={client}
41
- liveRates={{
42
- url: liveRatesUrl,
43
- options: { divisionCode, dataSource },
44
- }}
62
+ liveRates={liveRates}
45
63
  locale={locale}
46
64
  theme={theme}
47
65
  translations={translations}
@@ -59,6 +77,7 @@ const InstrumentsTableWidget = ({
59
77
  instruments={instruments}
60
78
  isAssetClassFilterEnabled={isAssetClassFilterEnabled}
61
79
  isInstrumentSearchEnabled={isInstrumentSearchEnabled}
80
+ isLiveRatesDisabled={liveRates === undefined}
62
81
  recordsPerPage={recordsPerPage}
63
82
  />
64
83
  </WidgetWrapper>
@@ -1,8 +1,13 @@
1
1
  import { useQuery } from '@apollo/client';
2
2
  import type { DataRecord } from '@oanda/labs-widget-common';
3
3
  import {
4
+ DataRecordType,
5
+ getHeaderConfig,
6
+ LastUpdated,
4
7
  Pagination,
8
+ Size,
5
9
  TableWidget,
10
+ useLayoutProvider,
6
11
  useLiveRatesQuery,
7
12
  } from '@oanda/labs-widget-common';
8
13
  import { useLocale } from '@oanda/mono-i18n';
@@ -14,9 +19,10 @@ import type { AssetClassName } from '../gql/types/graphql';
14
19
  import {
15
20
  type ResolveInstrumentsWithFiltersQuery,
16
21
  type ResolveInstrumentsWithFiltersQueryVariables,
22
+ TradeMode,
17
23
  } from '../gql/types/graphql';
18
24
  import { Filters } from './components';
19
- import { assetClassLabels, getHeaderConfig } from './config';
25
+ import { assetClassLabels, headerConfigs, tradeModeLabels } from './config';
20
26
  import { DEFAULT_COLUMNS, INSTRUMENT_TOOLTIP_ID } from './constant';
21
27
  import type { MainProps } from './types';
22
28
 
@@ -27,15 +33,23 @@ const Main = ({
27
33
  columns = DEFAULT_COLUMNS,
28
34
  isAssetClassFilterEnabled,
29
35
  isInstrumentSearchEnabled,
30
- recordsPerPage = 10,
36
+ recordsPerPage,
31
37
  dataSource,
38
+ isLiveRatesDisabled,
32
39
  }: MainProps) => {
33
40
  const documentRef = useRef<Document>(document);
41
+ const { size } = useLayoutProvider();
42
+ const isDesktop = size === Size.DESKTOP;
43
+ const isTradingMode =
44
+ columns.includes(DataRecordType.TRADE_MODE) &&
45
+ columns.includes(DataRecordType.SYMBOL);
46
+
34
47
  const { lang } = useLocale();
35
- const { target, setQuery, closeQuery } = useLiveRatesQuery();
48
+ const { target, setQuery, closeQuery } =
49
+ useLiveRatesQuery(isLiveRatesDisabled);
36
50
 
37
51
  const [records, setRecords] = useState<DataRecord[]>(
38
- new Array(recordsPerPage).fill({})
52
+ new Array(recordsPerPage || 10).fill({})
39
53
  );
40
54
 
41
55
  const [totalRecords, setTotalRecords] = useState<number>(0);
@@ -49,10 +63,18 @@ const Main = ({
49
63
  assetClass: assetClasses || [],
50
64
  instruments,
51
65
  dataSource,
66
+ withTradingModes: isTradingMode,
67
+ tradeModes: isTradingMode
68
+ ? [
69
+ TradeMode.TradeLongonly,
70
+ TradeMode.TradeShortonly,
71
+ TradeMode.TradeCloseonly,
72
+ ]
73
+ : undefined,
52
74
  });
53
75
 
54
76
  const pageNumber = queryVariables.offset
55
- ? Math.floor(queryVariables.offset / recordsPerPage)
77
+ ? Math.floor(queryVariables.offset / (recordsPerPage || 1))
56
78
  : 0;
57
79
 
58
80
  const { data, error, loading } = useQuery<
@@ -73,6 +95,11 @@ const Main = ({
73
95
  (record) => ({
74
96
  instrument: record?.name || '',
75
97
  displayName: record?.displayName || '',
98
+ tradeMode: lang(
99
+ tradeModeLabels[
100
+ (record?.tradeMode as keyof typeof tradeModeLabels) || ''
101
+ ]
102
+ ),
76
103
  })
77
104
  );
78
105
  setRecords(newRecords);
@@ -105,11 +132,17 @@ const Main = ({
105
132
 
106
133
  useEventListener('visibilitychange', onVisibilityChange, documentRef);
107
134
 
135
+ const headerConfig = !isDesktop
136
+ ? headerConfigs.mobile
137
+ : columns.length < 4
138
+ ? headerConfigs.longInstruments
139
+ : headerConfigs.normal;
140
+
108
141
  return (
109
142
  <>
110
143
  <TableWidget
111
144
  PaginationComponent={
112
- records.length > 0 ? (
145
+ records.length > 0 && recordsPerPage ? (
113
146
  <Pagination
114
147
  currentPage={pageNumber}
115
148
  disabled={loading}
@@ -167,7 +200,10 @@ const Main = ({
167
200
  activeColumns={columns}
168
201
  count={totalRecords}
169
202
  hasError={showError}
170
- headerColumns={getHeaderConfig(columns)}
203
+ headerColumns={getHeaderConfig(columns, headerConfig)}
204
+ instrumentColumnWidth={
205
+ headerConfig.instrument?.additionalStyles.minWidth
206
+ }
171
207
  isLoading={loading}
172
208
  pageNumber={pageNumber}
173
209
  records={records}
@@ -176,6 +212,14 @@ const Main = ({
176
212
  toolTipId={INSTRUMENT_TOOLTIP_ID}
177
213
  viewType="table"
178
214
  />
215
+ {!loading && !showError && isTradingMode && (
216
+ <div className="lw-mt-2 lw-h-8">
217
+ <LastUpdated
218
+ labelCallback={lang}
219
+ timestamp={data?.resolveInstrumentsWithFilters?.updatedAt}
220
+ />
221
+ </div>
222
+ )}
179
223
  </>
180
224
  );
181
225
  };
@@ -1,52 +1,114 @@
1
- import type { HeaderColumns } from '@oanda/labs-widget-common';
1
+ import type { HeaderConfigType } from '@oanda/labs-widget-common';
2
2
  import { DataRecordType } from '@oanda/labs-widget-common';
3
3
 
4
- import { AssetClassName } from '../gql/types/graphql';
4
+ import { AssetClassName, TradeMode } from '../gql/types/graphql';
5
5
  import type { AssetClassLabels } from './components/Filters/types';
6
6
 
7
- type HeaderRecordType =
8
- | DataRecordType.INSTRUMENT
9
- | DataRecordType.SELL
10
- | DataRecordType.BUY
11
- | DataRecordType.DAILY_CHANGE
12
- | DataRecordType.SPREAD
13
- | DataRecordType.HIGH
14
- | DataRecordType.LOW;
15
-
16
- const headerConfig: Record<
17
- HeaderRecordType,
18
- { displayName: string; additionalStyles: string }
7
+ const tradeModeLabels: Record<
8
+ TradeMode.TradeLongonly | TradeMode.TradeShortonly | TradeMode.TradeCloseonly,
9
+ string
19
10
  > = {
11
+ [TradeMode.TradeLongonly]: 'long_only',
12
+ [TradeMode.TradeShortonly]: 'short_only',
13
+ [TradeMode.TradeCloseonly]: 'close_only',
14
+ };
15
+ const normal: HeaderConfigType = {
20
16
  [DataRecordType.INSTRUMENT]: {
21
17
  displayName: 'instrument',
22
- additionalStyles: 'lw-text-left lw-min-w-[130px]',
18
+ additionalStyles: {
19
+ align: 'left',
20
+ minWidth: '200px',
21
+ },
23
22
  },
24
23
  [DataRecordType.SELL]: {
25
24
  displayName: 'sell',
26
- additionalStyles: 'lw-text-right lw-min-w-[75px] lw-pr-4',
25
+ additionalStyles: {
26
+ align: 'right',
27
+ minWidth: '75px',
28
+ paddingRight: true,
29
+ },
27
30
  },
28
31
  [DataRecordType.BUY]: {
29
32
  displayName: 'buy',
30
- additionalStyles: 'lw-text-right lw-min-w-[75px] lw-pr-4',
33
+ additionalStyles: {
34
+ align: 'right',
35
+ minWidth: '75px',
36
+ paddingRight: true,
37
+ },
31
38
  },
32
39
  [DataRecordType.SPREAD]: {
33
40
  displayName: 'spread',
34
- additionalStyles: 'lw-text-right lw-min-w-[50px]',
41
+ additionalStyles: {
42
+ align: 'right',
43
+ minWidth: '50px',
44
+ },
35
45
  },
36
46
  [DataRecordType.DAILY_CHANGE]: {
37
47
  displayName: 'daily_percent_change',
38
- additionalStyles: 'lw-text-right lw-min-w-[80px]',
48
+ additionalStyles: {
49
+ align: 'right',
50
+ minWidth: '80px',
51
+ },
39
52
  },
40
53
  [DataRecordType.HIGH]: {
41
54
  displayName: 'today_high',
42
- additionalStyles: 'lw-text-right lw-min-w-[80px]',
55
+ additionalStyles: {
56
+ align: 'right',
57
+ minWidth: '80px',
58
+ },
43
59
  },
44
60
  [DataRecordType.LOW]: {
45
61
  displayName: 'today_low',
46
- additionalStyles: 'lw-text-right lw-min-w-[80px]',
62
+ additionalStyles: {
63
+ align: 'right',
64
+ minWidth: '80px',
65
+ },
66
+ },
67
+ [DataRecordType.TRADE_MODE]: {
68
+ displayName: 'trade_mode',
69
+ additionalStyles: {
70
+ align: 'right',
71
+ minWidth: '80px',
72
+ paddingRight: true,
73
+ },
74
+ },
75
+ [DataRecordType.SYMBOL]: {
76
+ displayName: 'symbol',
77
+ additionalStyles: {
78
+ align: 'center',
79
+ minWidth: '80px',
80
+ },
81
+ },
82
+ };
83
+
84
+ const longInstruments: HeaderConfigType = {
85
+ ...normal,
86
+ [DataRecordType.INSTRUMENT]: {
87
+ displayName: 'instrument',
88
+ additionalStyles: {
89
+ align: 'left',
90
+ minWidth: '250px',
91
+ },
47
92
  },
48
93
  };
49
94
 
95
+ const mobile: HeaderConfigType = {
96
+ ...normal,
97
+ [DataRecordType.INSTRUMENT]: {
98
+ displayName: 'instrument',
99
+ additionalStyles: {
100
+ align: 'left',
101
+ minWidth: '150px',
102
+ },
103
+ },
104
+ };
105
+
106
+ const headerConfigs = {
107
+ normal,
108
+ longInstruments,
109
+ mobile,
110
+ };
111
+
50
112
  const assetClassLabels: Record<AssetClassLabels, string> = {
51
113
  ALL: 'all',
52
114
  [AssetClassName.Currency]: 'currency',
@@ -58,15 +120,4 @@ const assetClassLabels: Record<AssetClassLabels, string> = {
58
120
  [AssetClassName.Indices]: 'index',
59
121
  };
60
122
 
61
- const getHeaderConfig = (activeColumns: DataRecordType[]): HeaderColumns[] => {
62
- const columns: HeaderRecordType[] = [
63
- DataRecordType.INSTRUMENT,
64
- ...activeColumns,
65
- ].filter(
66
- (item): item is HeaderRecordType => item !== DataRecordType.SENTIMENT
67
- );
68
-
69
- return columns.map((item) => headerConfig[item]);
70
- };
71
-
72
- export { assetClassLabels, getHeaderConfig, headerConfig };
123
+ export { assetClassLabels, headerConfigs, tradeModeLabels };
@@ -33,4 +33,5 @@ export interface MainProps {
33
33
  isInstrumentSearchEnabled?: boolean;
34
34
  recordsPerPage?: number;
35
35
  dataSource: InstrumentDataSource;
36
+ isLiveRatesDisabled?: boolean;
36
37
  }
@@ -7,8 +7,10 @@ export const resolveInstrumentsWithFilters = gql`
7
7
  $dataSource: InstrumentDataSource
8
8
  $instruments: [String]
9
9
  $searchPattern: String
10
+ $tradeModes: [TradeMode]
10
11
  $count: Int
11
12
  $offset: Int
13
+ $withTradingModes: Boolean!
12
14
  ) {
13
15
  resolveInstrumentsWithFilters(
14
16
  division: $division
@@ -18,12 +20,15 @@ export const resolveInstrumentsWithFilters = gql`
18
20
  searchPattern: $searchPattern
19
21
  count: $count
20
22
  offset: $offset
23
+ tradeModes: $tradeModes
21
24
  ) {
22
25
  instruments {
23
26
  name
24
27
  displayName
28
+ tradeMode @include(if: $withTradingModes)
25
29
  }
26
30
  totalCount
31
+ updatedAt @include(if: $withTradingModes)
27
32
  }
28
33
  }
29
34
  `;
@@ -13,7 +13,7 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
13
13
  * Therefore it is highly recommended to use the babel or swc plugin for production.
14
14
  */
15
15
  const documents = {
16
- '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n':
16
+ '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n':
17
17
  types.ResolveInstrumentsWithFiltersDocument,
18
18
  };
19
19
 
@@ -35,8 +35,8 @@ export function graphql(source: string): unknown;
35
35
  * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
36
36
  */
37
37
  export function graphql(
38
- source: '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n'
39
- ): (typeof documents)['\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $count: Int\n $offset: Int\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n ) {\n instruments {\n name\n displayName\n }\n totalCount\n }\n }\n'];
38
+ source: '\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n'
39
+ ): (typeof documents)['\n query resolveInstrumentsWithFilters(\n $division: Division!\n $assetClass: [AssetClassName]\n $dataSource: InstrumentDataSource\n $instruments: [String]\n $searchPattern: String\n $tradeModes: [TradeMode]\n $count: Int\n $offset: Int\n $withTradingModes: Boolean!\n ) {\n resolveInstrumentsWithFilters(\n division: $division\n assetClass: $assetClass\n dataSource: $dataSource\n instruments: $instruments\n searchPattern: $searchPattern\n count: $count\n offset: $offset\n tradeModes: $tradeModes\n ) {\n instruments {\n name\n displayName\n tradeMode @include(if: $withTradingModes)\n }\n totalCount\n updatedAt @include(if: $withTradingModes)\n }\n }\n'];
40
40
 
41
41
  export function graphql(source: string) {
42
42
  return (documents as any)[source] ?? {};