Skip to content

Commit 2eddc32

Browse files
Merge branch 'Expensify:main' into 84252
2 parents 32ea6a5 + 7e70ab1 commit 2eddc32

561 files changed

Lines changed: 13510 additions & 8027 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009034200
115-
versionName "9.3.42-0"
114+
versionCode 1009034303
115+
versionName "9.3.43-3"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"
816 Bytes
Binary file not shown.

config/webpack/ModuleInitTimingPlugin.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type {Chunk, Compiler} from 'webpack';
1+
import path from 'path';
2+
import type {Chunk, Compiler, NormalModule} from 'webpack';
23
import webpack from 'webpack';
34
// @libs alias is not available in Node.js/Storybook context — use relative path instead
45
// @ts-expect-error -- Can't use .ts extensions without allowImportingTsExtensions in tsconfig
@@ -37,6 +38,9 @@ function createTimingRuntimeModule(): webpack.RuntimeModule {
3738
*/
3839
class ModuleInitTimingPlugin {
3940
apply(compiler: Compiler): void {
41+
if (compiler.isChild()) {
42+
return;
43+
}
4044
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
4145
// Ensure webpack generates the __webpack_require__.i interception
4246
// mechanism for every chunk that has a runtime.
@@ -49,6 +53,29 @@ class ModuleInitTimingPlugin {
4953
compilation.addRuntimeModule(chunk, createTimingRuntimeModule());
5054
});
5155
});
56+
57+
// Emit module-names.json once per build (after all compilations are sealed).
58+
// Using compiler.hooks.emit rather than compilation.hooks.processAssets avoids
59+
// conflicts when multiple compilation rounds run in the same build (e.g. Sentry plugin).
60+
compiler.hooks.emit.tap(PLUGIN_NAME, (compilation) => {
61+
const names: Record<string, string> = {};
62+
for (const module of compilation.modules) {
63+
const id = compilation.chunkGraph.getModuleId(module);
64+
if (id === null) {
65+
continue;
66+
}
67+
const resource = 'resource' in module ? (module as NormalModule).resource : undefined;
68+
if (!resource || resource.includes('node_modules')) {
69+
continue;
70+
}
71+
const relativePath = `./${path.relative(compiler.context, resource).replaceAll('\\', '/')}`;
72+
names[String(id)] = relativePath;
73+
}
74+
if (Object.keys(names).length > 0) {
75+
// eslint-disable-next-line no-param-reassign
76+
compilation.assets['module-names.json'] = new webpack.sources.RawSource(JSON.stringify(names));
77+
}
78+
});
5279
}
5380
}
5481

contributingGuides/OBSERVABILITY.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ This sends spans to the real Sentry project instead of the local console.
8484

8585
Defined in `src/CONST/index.ts` under `CONST.TELEMETRY`:
8686
- Span names: `SPAN_OPEN_REPORT`, `SPAN_SEND_MESSAGE`
87-
- Tag names: `TAG_ACTIVE_POLICY`, `TAG_AUTHENTICATION_ERROR_TYPE`
87+
- Tag names: `TAGS.ACTIVE_POLICY`, `TAGS.AUTHENTICATION_ERROR_TYPE`
8888
- Attribute names: `ATTRIBUTE_REPORT_ID`, `ATTRIBUTE_MESSAGE_LENGTH`
8989
- Configuration: `CONFIG.SKELETON_MIN_DURATION`
9090

@@ -163,7 +163,9 @@ Add span name, tags, and attributes to `src/CONST/index.ts`:
163163
```typescript
164164
TELEMETRY: {
165165
SPAN_YOUR_OPERATION: 'ManualYourOperation',
166-
TAG_YOUR_TAG: 'your_tag',
166+
TAGS: {
167+
YOUR_TAG: 'your_tag',
168+
},
167169
ATTRIBUTE_YOUR_ATTR: 'your_attr'
168170
}
169171
```
@@ -182,7 +184,7 @@ startSpan(spanId, {
182184
```typescript
183185
const span = getSpan(spanId);
184186
span?.setAttribute(CONST.TELEMETRY.ATTRIBUTE_YOUR_ATTR, value);
185-
span?.setTag(CONST.TELEMETRY.TAG_YOUR_TAG, value);
187+
span?.setTag(CONST.TELEMETRY.TAGS.YOUR_TAG, value);
186188
```
187189

188190
#### 5. Finish Span

contributingGuides/OBSERVABILITY_METRICS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ This document lists all implemented telemetry metrics in the Expensify App.
137137

138138
### Authentication Failures
139139

140-
**Constants**: `CONST.TELEMETRY.TAG_AUTHENTICATION_FUNCTION`, `CONST.TELEMETRY.TAG_AUTHENTICATION_ERROR_TYPE`, `CONST.TELEMETRY.TAG_AUTHENTICATION_JSON_CODE` ([`src/CONST/index.ts`](https://github.com/Expensify/App/blob/8f123f449f1a4533830b18a1040c9a5f1949821d/src/CONST/index.ts#L1700-L1702))
140+
**Constants**: `CONST.TELEMETRY.TAGS.AUTHENTICATION_FUNCTION`, `CONST.TELEMETRY.TAGS.AUTHENTICATION_ERROR_TYPE`, `CONST.TELEMETRY.TAGS.AUTHENTICATION_JSON_CODE` ([`src/CONST/index.ts`](https://github.com/Expensify/App/blob/8f123f449f1a4533830b18a1040c9a5f1949821d/src/CONST/index.ts#L1700-L1702))
141141
**What's Measured**: Number of authentication failures tracked via `Sentry.captureException()` using [`trackAuthenticationError()`](https://github.com/Expensify/App/blob/8f123f449f1a4533830b18a1040c9a5f1949821d/src/libs/telemetry/trackAuthenticationError.ts#L23)
142142
**Error Types**:
143143
- `missing_params`: Missing required auth parameters ([`Authentication.ts:66`](https://github.com/Expensify/App/blob/8f123f449f1a4533830b18a1040c9a5f1949821d/src/libs/Authentication.ts#L66))

contributingGuides/SELECTION_LIST.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This doc explains when and how to use the `SelectionList` and `SelectionListWith
88
There are two main components:
99

1010
- [**`SelectionList`**](../src/components/SelectionList/BaseSelectionList.tsx) - For displaying a single array of data (no sections)
11-
- [**`SelectionListWithSections`**](../src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx) - For displaying data organized into multiple sections
11+
- [**`SelectionListWithSections`**](../src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx) - For displaying data organized into multiple sections
1212

1313
## When to Use Each Component
1414

@@ -59,13 +59,18 @@ There are two main components:
5959
```tsx
6060
<SelectionListWithSections
6161
sections={[
62-
{ title: 'Recent', data: recentContacts },
63-
{ title: 'All Contacts', data: allContacts },
62+
{ title: 'Recent', data: recentContacts, sectionIndex: 0 },
63+
{ title: 'All Contacts', data: allContacts, sectionIndex: 1 },
6464
]}
6565
ListItem={UserListItem}
6666
onSelectRow={handleSelectContact}
6767
shouldShowTextInput
68-
textInputLabel="Search contacts"
68+
textInputOptions={{
69+
label: "Search items",
70+
value: searchText,
71+
onChangeText: setSearchText,
72+
headerMessage
73+
}}
6974
/>
7075
```
7176

cspell.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@
304304
"gradlew",
305305
"Grantmaking",
306306
"groupmonth",
307+
"groupweek",
307308
"gscb",
308309
"gsib",
309310
"gsst",
@@ -598,6 +599,7 @@
598599
"reactnativebackgroundtask",
599600
"reactnativehybridapp",
600601
"reactnativekeycommand",
602+
"reannounce",
601603
"reauthentication",
602604
"Reauthenticator",
603605
"Rebooked",

docs/_includes/search-result-item.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848

4949
<template id="ai-response-template">
5050
<div class="ai-panel">
51+
<button class="ai-copy-button" title="Copy to clipboard">
52+
<img src="/assets/images/copy.svg" class="ai-copy-icon ai-copy-icon-light" />
53+
<img src="/assets/images/copy-dark.svg" class="ai-copy-icon ai-copy-icon-dark" />
54+
<img src="/assets/images/checkmark.svg" class="ai-checkmark-icon ai-checkmark-icon-light" />
55+
<img src="/assets/images/checkmark-dark.svg" class="ai-checkmark-icon ai-checkmark-icon-dark" />
56+
</button>
5157
<div class="ai-header">
5258
<img src="/assets/images/concierge-avatar.svg" class="ai-avatar" />
5359
<span class="ai-title">Concierge AI summary:</span>

docs/_sass/_main.scss

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,7 @@ button {
11581158
box-sizing: border-box;
11591159
display: flex;
11601160
flex-direction: column;
1161+
position: relative;
11611162

11621163
&.ai-panel-loading {
11631164
min-height: 320px;
@@ -1168,6 +1169,71 @@ button {
11681169
}
11691170
}
11701171

1172+
.ai-copy-button {
1173+
position: absolute;
1174+
top: 16px;
1175+
right: 16px;
1176+
width: 28px;
1177+
height: 28px;
1178+
padding: 0;
1179+
border: none;
1180+
border-radius: 50%;
1181+
background-color: var(--color-row-hover);
1182+
cursor: pointer;
1183+
display: flex;
1184+
align-items: center;
1185+
justify-content: center;
1186+
1187+
&:hover {
1188+
background-color: var(--color-button-background-hover);
1189+
}
1190+
1191+
img {
1192+
width: 12px;
1193+
height: 12px;
1194+
display: block;
1195+
}
1196+
1197+
.ai-copy-icon-dark,
1198+
.ai-checkmark-icon {
1199+
display: none;
1200+
}
1201+
1202+
@media (prefers-color-scheme: dark) {
1203+
.ai-copy-icon-light {
1204+
display: none;
1205+
}
1206+
1207+
.ai-copy-icon-dark {
1208+
display: block;
1209+
}
1210+
}
1211+
1212+
&.copied {
1213+
.ai-copy-icon {
1214+
display: none;
1215+
}
1216+
1217+
.ai-checkmark-icon-light {
1218+
display: block;
1219+
}
1220+
1221+
.ai-checkmark-icon-dark {
1222+
display: none;
1223+
}
1224+
1225+
@media (prefers-color-scheme: dark) {
1226+
.ai-checkmark-icon-light {
1227+
display: none;
1228+
}
1229+
1230+
.ai-checkmark-icon-dark {
1231+
display: block;
1232+
}
1233+
}
1234+
}
1235+
}
1236+
11711237
.ai-avatar {
11721238
width: 32px;
11731239
height: 32px;

0 commit comments

Comments
 (0)