@admin-layout/gluestack-ui-mobile 12.2.4-alpha.85 → 12.2.5-alpha.13

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 (39) hide show
  1. package/CHANGELOG.md +9 -77
  2. package/lib/components/FlightCards/FlightCards.d.ts +40 -0
  3. package/lib/components/FlightCards/FlightCards.js +134 -0
  4. package/lib/components/FlightCards/FlightCards.js.map +1 -0
  5. package/lib/components/FlightCards/index.d.ts +2 -0
  6. package/lib/components/FlightCards/index.js +2 -0
  7. package/lib/components/FlightCards/index.js.map +1 -0
  8. package/lib/components/InputToolBar/InputToolBar.js +8 -4
  9. package/lib/components/InputToolBar/InputToolBar.js.map +1 -1
  10. package/lib/components/WithConfiguration.d.ts +1 -6
  11. package/lib/components/WithConfiguration.js +1 -4
  12. package/lib/components/WithConfiguration.js.map +1 -1
  13. package/lib/components/WithPermission.d.ts +1 -11
  14. package/lib/components/WithPermission.js +0 -8
  15. package/lib/components/WithPermission.js.map +1 -1
  16. package/lib/components/index.d.ts +1 -0
  17. package/lib/components/index.js +1 -0
  18. package/lib/components/index.js.map +1 -1
  19. package/lib/components/usePermissionAutoFetch.d.ts +4 -56
  20. package/lib/components/usePermissionAutoFetch.js +7 -19
  21. package/lib/components/usePermissionAutoFetch.js.map +1 -1
  22. package/lib/components/useSetting.d.ts +11 -6
  23. package/lib/components/useSetting.js +10 -75
  24. package/lib/components/useSetting.js.map +1 -1
  25. package/lib/tailwind.config.js +3 -0
  26. package/lib/tailwind.config.js.map +1 -1
  27. package/lib/utils/generateMobileNavigations.js +37 -8
  28. package/lib/utils/generateMobileNavigations.js.map +1 -1
  29. package/package.json +6 -6
  30. package/src/components/FlightCards/FlightCards.tsx +266 -0
  31. package/src/components/FlightCards/index.ts +2 -0
  32. package/src/components/InputToolBar/InputToolBar.tsx +8 -4
  33. package/src/components/WithConfiguration.tsx +1 -5
  34. package/src/components/WithPermission.tsx +0 -9
  35. package/src/components/index.ts +1 -0
  36. package/src/components/usePermissionAutoFetch.tsx +7 -22
  37. package/src/components/useSetting.tsx +22 -100
  38. package/src/tailwind.config.js +202 -198
  39. package/src/utils/generateMobileNavigations.ts +34 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@admin-layout/gluestack-ui-mobile",
3
- "version": "12.2.4-alpha.85",
3
+ "version": "12.2.5-alpha.13",
4
4
  "description": "Glustack-ui for mobile component layout",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -23,7 +23,7 @@
23
23
  "watch": "npm run build:lib:watch"
24
24
  },
25
25
  "dependencies": {
26
- "@admin-layout/client": "12.2.4-alpha.85",
26
+ "@admin-layout/client": "12.2.5-alpha.7",
27
27
  "@gluestack-style/react": "^1.0.53",
28
28
  "@gluestack-ui/config": "^1.1.18",
29
29
  "@gluestack-ui/nativewind-utils": "^1.0.26",
@@ -36,10 +36,10 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/react-window": "^1.8.8",
39
- "common": "12.2.4-alpha.85"
39
+ "common": "12.2.5-alpha.2"
40
40
  },
41
41
  "peerDependencies": {
42
- "@common-stack/remix-router-redux": "^6.0.2-alpha.2",
42
+ "@common-stack/remix-router-redux": "^9.2.1-alpha.0",
43
43
  "i18next": "^23.10.1",
44
44
  "react-i18next": "^14.1.0",
45
45
  "react-native-svg": "13.9.0"
@@ -47,8 +47,8 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "57ad95f9f2fb3faed22f90ac047bde3eca75340f",
51
50
  "typescript": {
52
51
  "definition": "lib/index.d.ts"
53
- }
52
+ },
53
+ "gitHead": "b9693200e37d90e37a34dc27b7a30ac6c861bc06"
54
54
  }
@@ -0,0 +1,266 @@
1
+ import React, { memo } from 'react';
2
+ import { Pressable, ScrollView, StyleSheet, Text, View, useColorScheme, useWindowDimensions } from 'react-native';
3
+ import Svg, { Line, Path } from 'react-native-svg';
4
+ import { toFlightCards } from '@admin-layout/client';
5
+ import type { FlightCardView, FlightOfferSetLike, FlightSliceView } from '@admin-layout/client';
6
+
7
+ /**
8
+ * Flight results for a mobile chat: the native twin of ai-chat-ext's web
9
+ * MessageFlights. Both render from @admin-layout/client's flight model, so a
10
+ * flight reads the same (times, +1, stops, price) on the web and in the app.
11
+ */
12
+
13
+ export interface FlightCardColors {
14
+ card: string;
15
+ border: string;
16
+ ink: string;
17
+ muted: string;
18
+ faint: string;
19
+ accent: string;
20
+ price: string;
21
+ nextDay: string;
22
+ }
23
+
24
+ const LIGHT: FlightCardColors = {
25
+ card: '#ffffff',
26
+ border: '#e5e7eb',
27
+ ink: '#111827',
28
+ muted: '#6b7280',
29
+ faint: '#9ca3af',
30
+ accent: '#3b82f6',
31
+ price: '#2563eb',
32
+ nextDay: '#d97706',
33
+ };
34
+
35
+ const DARK: FlightCardColors = {
36
+ card: '#1f2937',
37
+ border: '#374151',
38
+ ink: '#f9fafb',
39
+ muted: '#9ca3af',
40
+ faint: '#6b7280',
41
+ accent: '#60a5fa',
42
+ price: '#60a5fa',
43
+ nextDay: '#fbbf24',
44
+ };
45
+
46
+ const GAP = 12;
47
+ const SIDE = 8;
48
+
49
+ export interface FlightCardRowProps {
50
+ attachment: FlightOfferSetLike & { totalCount?: number; title?: string; actionLabel?: string };
51
+ /** Open a bookable offer. The host decides how: system browser, in-app browser. */
52
+ onOpenOffer?: (url: string) => void;
53
+ /** Open the full result set. Also used by a card that has no seller link. */
54
+ onViewAll?: () => void;
55
+ /** Override the palette; defaults follow the system light/dark scheme. */
56
+ colors?: Partial<FlightCardColors>;
57
+ }
58
+
59
+ const Plane = ({ color }: { color: string }) => (
60
+ <Svg width={14} height={14} viewBox="0 0 24 24" style={styles.plane}>
61
+ <Path
62
+ fill={color}
63
+ d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"
64
+ />
65
+ </Svg>
66
+ );
67
+
68
+ // An SVG line, not a dashed border: iOS does not draw borderStyle 'dashed'
69
+ // on a single side, so the route line would vanish on iPhones.
70
+ const Dashes = ({ color }: { color: string }) => (
71
+ <Svg height={2} width="100%" style={styles.dashes}>
72
+ <Line x1="0" y1="1" x2="100%" y2="1" stroke={color} strokeWidth={1} strokeDasharray="4 3" />
73
+ </Svg>
74
+ );
75
+
76
+ const SliceRow = ({ slice, c }: { slice: FlightSliceView; c: FlightCardColors }) => {
77
+ return (
78
+ <View style={styles.slice}>
79
+ <View>
80
+ <Text style={[styles.time, { color: c.ink }]}>{slice.departTime ?? '--:--'}</Text>
81
+ <Text style={[styles.code, { color: c.muted }]}>{slice.origin}</Text>
82
+ </View>
83
+ <View style={styles.route} importantForAccessibility="no-hide-descendants" accessibilityElementsHidden>
84
+ <View style={styles.routeLine}>
85
+ <Dashes color={c.border} />
86
+ <Plane color={c.accent} />
87
+ <Dashes color={c.border} />
88
+ </View>
89
+ {slice.meta ? (
90
+ <Text style={[styles.meta, { color: c.faint }]} numberOfLines={1}>
91
+ {slice.meta}
92
+ </Text>
93
+ ) : null}
94
+ </View>
95
+ <View style={styles.arrive}>
96
+ <View style={styles.arriveTime}>
97
+ <Text style={[styles.time, { color: c.ink }]}>{slice.arriveTime ?? '--:--'}</Text>
98
+ {slice.dayOffset ? (
99
+ <Text style={[styles.nextDay, { color: c.nextDay }]}>{slice.dayOffset}</Text>
100
+ ) : null}
101
+ </View>
102
+ <Text style={[styles.code, styles.right, { color: c.muted }]}>{slice.destination}</Text>
103
+ </View>
104
+ </View>
105
+ );
106
+ };
107
+
108
+ export const FlightCard = memo(function FlightCard({
109
+ card,
110
+ width,
111
+ colors: c,
112
+ onPress,
113
+ }: {
114
+ card: FlightCardView;
115
+ width: number | '100%';
116
+ colors: FlightCardColors;
117
+ onPress?: () => void;
118
+ }) {
119
+ const body = (
120
+ <>
121
+ <View style={styles.header}>
122
+ {card.sellerInitial ? (
123
+ <View style={[styles.badge, { backgroundColor: c.accent }]}>
124
+ <Text style={styles.badgeText}>{card.sellerInitial}</Text>
125
+ </View>
126
+ ) : null}
127
+ <Text style={[styles.headerText, { color: c.muted }]} numberOfLines={1}>
128
+ {card.header}
129
+ </Text>
130
+ </View>
131
+ <View style={styles.slices}>
132
+ {card.slices.map((s, i) => (
133
+ <SliceRow key={i} slice={s} c={c} />
134
+ ))}
135
+ </View>
136
+ <View style={[styles.footer, { borderTopColor: c.border }]}>
137
+ <Text style={[styles.footerText, { color: c.muted }]} numberOfLines={1}>
138
+ {card.footer}
139
+ </Text>
140
+ {card.price ? <Text style={[styles.price, { color: c.price }]}>{card.price}</Text> : null}
141
+ </View>
142
+ </>
143
+ );
144
+ const frame = [styles.card, { width, backgroundColor: c.card, borderColor: c.border }];
145
+ if (!onPress) {
146
+ return (
147
+ <View style={frame} accessible accessibilityLabel={card.accessibleLabel} testID="flight-card">
148
+ {body}
149
+ </View>
150
+ );
151
+ }
152
+ return (
153
+ <Pressable
154
+ onPress={onPress}
155
+ accessibilityRole={card.url ? 'link' : 'button'}
156
+ accessibilityLabel={card.accessibleLabel}
157
+ style={({ pressed }) => [...frame, pressed && styles.pressed]}
158
+ testID="flight-card"
159
+ >
160
+ {body}
161
+ </Pressable>
162
+ );
163
+ });
164
+
165
+ const usePalette = (overrides?: Partial<FlightCardColors>): FlightCardColors => {
166
+ const dark = useColorScheme() === 'dark';
167
+ return { ...(dark ? DARK : LIGHT), ...overrides };
168
+ };
169
+
170
+ /** A swipeable row of flight cards; the next card peeks in so the row reads as scrollable. */
171
+ export function FlightCardRow({ attachment, onOpenOffer, onViewAll, colors }: FlightCardRowProps) {
172
+ const c = usePalette(colors);
173
+ const { width: screen } = useWindowDimensions();
174
+ const cards = toFlightCards(attachment);
175
+ if (cards.length === 0) return null;
176
+
177
+ const cardWidth = Math.round(Math.min(304, screen * 0.8));
178
+ const count = attachment.totalCount ?? attachment.properties?.length ?? cards.length;
179
+ const press = (card: FlightCardView) =>
180
+ card.url && onOpenOffer ? () => onOpenOffer(card.url as string) : onViewAll;
181
+
182
+ return (
183
+ <View style={styles.wrap} accessibilityLabel={attachment.title || 'Flight options'}>
184
+ <ScrollView
185
+ horizontal
186
+ nestedScrollEnabled
187
+ showsHorizontalScrollIndicator={false}
188
+ // One card per swipe, landing flush with the row's side inset.
189
+ snapToInterval={cardWidth + GAP}
190
+ snapToAlignment="start"
191
+ decelerationRate="fast"
192
+ contentContainerStyle={styles.row}
193
+ testID="flight-row"
194
+ >
195
+ {cards.map((card) => (
196
+ <FlightCard key={card.key} card={card} width={cardWidth} colors={c} onPress={press(card)} />
197
+ ))}
198
+ </ScrollView>
199
+ {onViewAll && count > cards.length ? (
200
+ <Pressable onPress={onViewAll} accessibilityRole="button" hitSlop={8} style={styles.viewAll}>
201
+ <Text style={[styles.viewAllText, { color: c.price }]}>
202
+ {attachment.actionLabel || `View all ${count} flights`} ›
203
+ </Text>
204
+ </Pressable>
205
+ ) : null}
206
+ </View>
207
+ );
208
+ }
209
+
210
+ /** Every flight as a full-width vertical list, for a results screen or sheet. */
211
+ export function FlightCardList({ attachment, onOpenOffer, onViewAll, colors }: FlightCardRowProps) {
212
+ const c = usePalette(colors);
213
+ const cards = toFlightCards(attachment);
214
+ if (cards.length === 0) return null;
215
+ return (
216
+ <View style={styles.list}>
217
+ {cards.map((card) => (
218
+ <FlightCard
219
+ key={card.key}
220
+ card={card}
221
+ width="100%"
222
+ colors={c}
223
+ onPress={card.url && onOpenOffer ? () => onOpenOffer(card.url as string) : onViewAll}
224
+ />
225
+ ))}
226
+ </View>
227
+ );
228
+ }
229
+
230
+ const styles = StyleSheet.create({
231
+ wrap: { marginVertical: 8 },
232
+ row: { paddingHorizontal: SIDE, paddingVertical: 4, gap: GAP },
233
+ list: { gap: GAP },
234
+ card: { borderWidth: 1, borderRadius: 16, padding: 16 },
235
+ pressed: { opacity: 0.85 },
236
+ header: { flexDirection: 'row', alignItems: 'center', gap: 8 },
237
+ badge: { width: 20, height: 20, borderRadius: 6, alignItems: 'center', justifyContent: 'center' },
238
+ badgeText: { color: '#ffffff', fontSize: 11, fontWeight: '700' },
239
+ headerText: { flex: 1, fontSize: 14 },
240
+ slices: { marginVertical: 16, gap: 16 },
241
+ slice: { flexDirection: 'row', alignItems: 'center', gap: 12 },
242
+ time: { fontSize: 24, fontWeight: '700', letterSpacing: -0.5, fontVariant: ['tabular-nums'] },
243
+ code: { marginTop: 4, fontSize: 14 },
244
+ right: { textAlign: 'right' },
245
+ route: { flex: 1, alignItems: 'center', minWidth: 0 },
246
+ routeLine: { flexDirection: 'row', alignItems: 'center', alignSelf: 'stretch', gap: 6 },
247
+ dashes: { flex: 1 },
248
+ plane: { transform: [{ rotate: '90deg' }] },
249
+ meta: { marginTop: 4, fontSize: 11 },
250
+ arrive: { alignItems: 'flex-end' },
251
+ arriveTime: { flexDirection: 'row', alignItems: 'flex-start' },
252
+ nextDay: { marginLeft: 2, fontSize: 11, fontWeight: '600' },
253
+ footer: {
254
+ marginTop: 'auto',
255
+ flexDirection: 'row',
256
+ alignItems: 'center',
257
+ justifyContent: 'space-between',
258
+ gap: 12,
259
+ borderTopWidth: 1,
260
+ paddingTop: 12,
261
+ },
262
+ footerText: { flex: 1, fontSize: 14 },
263
+ price: { fontSize: 18, fontWeight: '700', fontVariant: ['tabular-nums'] },
264
+ viewAll: { marginTop: 4, marginHorizontal: SIDE, alignSelf: 'flex-start' },
265
+ viewAllText: { fontSize: 14, fontWeight: '600' },
266
+ });
@@ -0,0 +1,2 @@
1
+ export { FlightCard, FlightCardRow, FlightCardList } from './FlightCards';
2
+ export type { FlightCardRowProps, FlightCardColors } from './FlightCards';
@@ -1,5 +1,5 @@
1
1
  import React, { useMemo, useState } from 'react';
2
- import { TextInput, Modal, ScrollView, Pressable, Text as RNText, Dimensions } from 'react-native';
2
+ import { TextInput, Modal, ScrollView, Pressable, Text as RNText, Dimensions, useColorScheme } from 'react-native';
3
3
  import { Box, HStack, VStack, Text, Pressable as GluestackPressable } from '@gluestack-ui/themed';
4
4
  import { Ionicons, Feather } from '@expo/vector-icons';
5
5
  import type {
@@ -541,6 +541,10 @@ export function InputToolBar({
541
541
  const rightItems = rightItemsProp ?? [];
542
542
  const hasInputContent = inputConfig != null || children != null;
543
543
  const effectiveTopContent = inputConfig != null ? topContent : null;
544
+ const isDark = useColorScheme() === 'dark';
545
+ const composerBg = isDark ? '#1e293b' : '$white';
546
+ const composerText = isDark ? '#e2e8f0' : '#18181b';
547
+ const composerPlaceholder = isDark ? '#94a3b8' : '#71717a';
544
548
 
545
549
  const templateModal =
546
550
  templateModalConfig != null && templateModalConfig.isOpen
@@ -559,7 +563,7 @@ export function InputToolBar({
559
563
  w="100%"
560
564
  overflow="visible"
561
565
  rounded="$3xl"
562
- bg="$white"
566
+ bg={composerBg}
563
567
  shadowColor="$black"
564
568
  shadowOffset={{ width: 0, height: 4 }}
565
569
  shadowOpacity={0.08}
@@ -581,7 +585,7 @@ export function InputToolBar({
581
585
  value={inputConfig.value}
582
586
  onChange={inputConfig.onChange}
583
587
  placeholder={inputConfig.placeholder ?? 'Ask anything...'}
584
- placeholderTextColor="#71717a"
588
+ placeholderTextColor={composerPlaceholder}
585
589
  editable={!inputConfig.disabled}
586
590
  multiline
587
591
  numberOfLines={1}
@@ -589,7 +593,7 @@ export function InputToolBar({
589
593
  width: '100%',
590
594
  minHeight: 44,
591
595
  fontSize: 16,
592
- color: '#18181b',
596
+ color: composerText,
593
597
  paddingVertical: 8,
594
598
  paddingHorizontal: 0,
595
599
  margin: 0,
@@ -16,7 +16,7 @@ export interface IWithConfigurationProps {
16
16
  }
17
17
 
18
18
  export const WithConfiguration = (props: IWithConfigurationProps) => {
19
- const { configKey, children, permissionKeys, resourceName, permissionTypes } = props;
19
+ const { configKey, children, permissionKeys, resourceName, permissionTypes = [PermissionType.Allow] } = props;
20
20
 
21
21
  const {
22
22
  data,
@@ -65,8 +65,4 @@ export const WithConfiguration = (props: IWithConfigurationProps) => {
65
65
  );
66
66
  };
67
67
 
68
- WithConfiguration.defaultProps = {
69
- permissionTypes: [PermissionType.Allow],
70
- };
71
-
72
68
  export const WithConfigurationContainer = (props: IWithConfigurationProps) => <WithConfiguration {...props} />;
@@ -68,15 +68,6 @@ export const WithPermission = ({
68
68
  return null;
69
69
  };
70
70
 
71
- WithPermission.defaultProps = {
72
- permissionTypes: [PermissionType.Allow],
73
- behaviour: WithPermissionBehaviour.hide,
74
- message: "You don't have permission to access this resource, contact owner",
75
- disabledProps: {
76
- disabled: true,
77
- },
78
- };
79
-
80
71
  export const WithPermissionContainer = React.memo((props: IWithPermissionProps) => <WithPermission {...props} />);
81
72
  export default WithPermissionContainer;
82
73
  // export const WithPermissionContainer = (props: IWithPermissionProps) => <WithPermission {...props} />;
@@ -14,3 +14,4 @@ export * from './WithConfiguration';
14
14
  export * from './WithPolicy';
15
15
  export * from './usePermissionAutoFetch';
16
16
  export * from './useSetting';
17
+ export * from './FlightCards';
@@ -1,31 +1,16 @@
1
- import { ResourceAuthority, ConfigFragmentName, IContext } from 'common';
2
- import { generateUserUri } from '@adminide-stack/core';
3
- import { useGetContextDataQuery } from 'common/lib/generated/generated.js';
4
- import { useSetting } from './useSetting';
5
- import type { URI } from '@vscode-alt/monaco-editor/esm/vs/base/common/uri.js';
1
+ import { usePermissionAutoFetch as usePlatformPermissionAutoFetch } from '@adminide-stack/platform-client';
6
2
 
7
3
  interface userPermissionAutoFetchProps {
8
4
  configKey?: string;
9
5
  }
10
6
  export const usePermissionAutoFetch = (options?: userPermissionAutoFetchProps) => {
11
- const { data, loading } = useGetContextDataQuery();
12
- const { orgResource, userId } = (data?.getContextData as IContext) || {};
7
+ const { permissions, loading } = usePlatformPermissionAutoFetch(options);
13
8
 
14
- let resource = orgResource || (userId ? generateUserUri({ _id: userId }) : generateUserUri({ _id: 'guest' }));
15
-
16
- const { loading: settingLoading, ...remaining } = useSetting({
17
- configKey: options?.configKey || '',
18
- overrides: {
19
- resource: resource as unknown as URI,
20
- },
21
- options: {
22
- forceExist: false,
23
- authority: ResourceAuthority.Defaultpermissions,
24
- fragment: ConfigFragmentName.Roles,
25
- },
26
- });
27
-
28
- return { ...remaining, loading: loading || settingLoading };
9
+ return {
10
+ permissions,
11
+ data: permissions === undefined ? undefined : { resolveConfiguration: permissions },
12
+ loading,
13
+ };
29
14
  };
30
15
 
31
16
  // import React from 'react';
@@ -1,30 +1,25 @@
1
- import React from 'react';
2
1
  import type {
3
- IResolveConfigurationQuery,
4
- IResolveConfigurationQueryVariables,
2
+ IConfigurationsFlattenedKeys,
5
3
  IPreferencesInput,
6
4
  IPreferencesOpenOptionsInput,
7
- IUpdateConfigurationMutation,
8
5
  IConfigurationOverridesInput,
9
6
  } from 'common';
10
7
  import { ConfigurationTarget } from 'common';
11
- import { QueryResult } from '@apollo/client/react';
12
- import { omitBy, isNil } from 'lodash-es';
13
- import { ExecutionResult } from 'graphql';
14
- import {
15
- useResolveConfigurationQuery,
16
- useOpenPreferencesSettingsQuery,
17
- useUpdateConfigurationMutation,
18
- } from 'common/lib/generated/generated.js';
8
+ import { useSetting as usePlatformSetting } from '@adminide-stack/platform-client';
19
9
 
20
10
  export interface ISettingsVariable {
21
11
  overrides?: IConfigurationOverridesInput;
22
- configKey: string;
12
+ configKey: IConfigurationsFlattenedKeys;
23
13
  options?: IPreferencesOpenOptionsInput;
24
14
  skip?: boolean;
25
15
  }
26
16
 
27
- interface IResponse extends QueryResult<IResolveConfigurationQuery, IResolveConfigurationQueryVariables> {
17
+ interface IResponse {
18
+ data?: {
19
+ resolveConfiguration?: unknown;
20
+ };
21
+ loading: boolean;
22
+ error?: unknown;
28
23
  preferencesInput?: IPreferencesInput;
29
24
  updateConfiguration?: ({
30
25
  updateKey,
@@ -36,7 +31,9 @@ interface IResponse extends QueryResult<IResolveConfigurationQuery, IResolveConf
36
31
  value: string | boolean | number;
37
32
  updateOverrides?: IConfigurationOverridesInput;
38
33
  target?: ConfigurationTarget;
39
- }) => Promise<ExecutionResult<IUpdateConfigurationMutation>>;
34
+ }) => Promise<unknown>;
35
+ refetch?: Function;
36
+ [key: string]: unknown;
40
37
  }
41
38
 
42
39
  /**
@@ -45,93 +42,18 @@ interface IResponse extends QueryResult<IResolveConfigurationQuery, IResolveConf
45
42
  * @param baseOptions
46
43
  */
47
44
  export const useSetting = (settingsVariable: ISettingsVariable): IResponse => {
48
- const { overrides, configKey, options, skip = false } = settingsVariable;
49
- const targetResource = overrides?.resource ?? null;
50
- let prefLoaded = false;
51
- const {
52
- data: prefData,
53
- error: prefError,
54
- loading: perfLoading,
55
- refetch: refetchPrefData,
56
- } = useOpenPreferencesSettingsQuery({
57
- variables: { resource: targetResource, options },
58
- fetchPolicy: 'cache-first', // to make `{always: true}` to work
59
- skip: prefLoaded,
60
- });
61
- React.useEffect(() => {
62
- refetchPrefData({ resource: targetResource, options });
63
- }, [targetResource]);
64
- prefLoaded = perfLoading || skip;
65
- const [updateConfigurationMutation] = useUpdateConfigurationMutation();
66
- const modifiedOverrides = {
67
- ...overrides,
68
- resource: targetResource ? prefData?.openPreferencesSettings?.editableSettingsInput ?? null : null,
69
- };
70
- const defaultOverrides = omitBy(modifiedOverrides, isNil);
71
- let {
72
- data: settingsData,
73
- error: settingError,
74
- loading: settingLoading,
75
- ...remaining
76
- } = useResolveConfigurationQuery({
77
- variables: {
78
- input: prefData?.openPreferencesSettings ?? null,
79
- key: configKey,
80
- overrides: defaultOverrides,
81
- },
82
- fetchPolicy: 'cache-and-network', // to make `{always: true}` to work
83
- skip: prefLoaded || !!prefError || !prefData?.openPreferencesSettings?.editableSettingsInput,
84
- });
85
- React.useEffect(() => {
86
- remaining?.refetch({
87
- input: prefData?.openPreferencesSettings ?? null,
88
- key: configKey,
89
- overrides: defaultOverrides,
90
- });
91
- }, [prefData]);
92
-
93
- let loading = true;
94
- if (!settingLoading && !prefLoaded) {
95
- loading = false;
96
- }
97
- const error = settingError || prefError;
98
- if (error) {
99
- return {
100
- error,
101
- data: undefined,
102
- loading: false,
103
- ...remaining,
104
- };
105
- }
106
- if (loading) {
107
- return {
108
- error,
109
- data: undefined,
110
- loading,
111
- ...remaining,
112
- };
113
- }
114
-
115
- const updateConfiguration = ({ value, updateKey, updateOverrides, target }) => {
116
- return updateConfigurationMutation({
117
- variables: {
118
- key: updateKey || configKey,
119
- value,
120
- target,
121
- overrides: updateOverrides || defaultOverrides,
122
- input: prefData?.openPreferencesSettings,
123
- },
124
- });
125
- };
45
+ const { data, updateConfiguration, ...remaining } = usePlatformSetting(settingsVariable as any);
126
46
 
127
47
  return {
128
- data: settingsData,
129
- loading,
130
- error,
48
+ data: data === undefined ? undefined : { resolveConfiguration: data },
131
49
  ...remaining,
132
- preferencesInput: {
133
- ...prefData?.openPreferencesSettings,
50
+ updateConfiguration: ({ value, updateKey, updateOverrides, target }) => {
51
+ return updateConfiguration?.({
52
+ value,
53
+ updateKey,
54
+ updateOverrides,
55
+ target,
56
+ });
134
57
  },
135
- updateConfiguration,
136
- } as any;
58
+ };
137
59
  };