Skip to content

Commit b57b257

Browse files
chioljihun
andauthored
feat: minor bugs (#1418)
* fix: minor bugs * feat: reset row selection in user management and feedback tables * fix: update dependencies in useEffect for field setting component * fix: update next.config file extension in Dockerfile * refactor: simplify query state management and improve filter handling * fix: ensure setOperator is awaited in feedback and issue query converters * feat: add linkify and linkify-react for enhanced text linking in feedback and sheet detail views * fix: update Tooltip behavior to open when no projectId is selected * feat: add operator prop to TableFilterPopover and update related components * feat: add operator prop to TableFilterPopover in user management and member settings --------- Co-authored-by: jeehoon.choi <jeehoon.choi@linecorp.com>
1 parent 3d01422 commit b57b257

33 files changed

+203
-145
lines changed

apps/cli/bin/auf-cli.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,7 @@ program
106106
const tomlContent = fs.readFileSync(destinationConfigPath, 'utf-8');
107107
const tomlConfig = load(tomlContent) as TomlConfig;
108108

109-
const webEnvVars = [
110-
'NEXT_PUBLIC_API_BASE_URL',
111-
'NEXT_PUBLIC_MAX_DAYS',
112-
'SESSION_PASSWORD',
113-
];
109+
const webEnvVars = ['NEXT_PUBLIC_API_BASE_URL', 'NEXT_PUBLIC_MAX_DAYS'];
114110

115111
const apiEnvVars = [
116112
'JWT_SECRET',

apps/cli/config.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,3 @@ MASTER_API_KEY="MASTER_API_KEY"
1818
[web]
1919
NEXT_PUBLIC_API_BASE_URL="http://localhost:4000"
2020
NEXT_PUBLIC_MAX_DAYS=90
21-
SESSION_PASSWORD="sessionpasswordsessionpasswordsessionpassword"

apps/cli/docker-compose.template.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ services:
1010
environment:
1111
- NEXT_PUBLIC_API_BASE_URL=${NEXT_PUBLIC_API_BASE_URL}
1212
- NEXT_PUBLIC_MAX_DAYS=${NEXT_PUBLIC_MAX_DAYS}
13-
- SESSION_PASSWORD=${SESSION_PASSWORD}
1413
depends_on:
1514
- api
1615

apps/web/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,9 @@ pnpm build
6363

6464
### Required Environment Variables
6565

66-
| Environment | Description | Default Value |
67-
| ------------------------ | ------------------------------------------------------- | -------------------------------------------- |
68-
| NEXT_PUBLIC_API_BASE_URL | api base url in client side (ex. http://localhost:4000) | |
69-
| SESSION_PASSWORD | session password | complex_password_at_least_32_characters_long |
66+
| Environment | Description | Default Value |
67+
| ------------------------ | ------------------------------------------------------- | ------------- |
68+
| NEXT_PUBLIC_API_BASE_URL | api base url in client side (ex. http://localhost:4000) | |
7069

7170
### Optional Environment Variables
7271

apps/web/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
"i18next": "^24.0.0",
5959
"immer": "^10.0.4",
6060
"jwt-decode": "^4.0.0",
61+
"linkify": "^0.2.1",
62+
"linkify-react": "^4.2.0",
6163
"next": "^15.0.0",
6264
"next-i18next": "^15.3.0",
6365
"next-themes": "^0.4.3",

apps/web/src/entities/feedback/lib/use-feedback-query-converter.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
* under the License.
1515
*/
1616

17-
import { useCallback, useMemo, useState } from 'react';
17+
import { useCallback, useMemo } from 'react';
1818
import dayjs from 'dayjs';
19-
import { createParser, useQueryState } from 'nuqs';
19+
import { createParser, parseAsStringLiteral, useQueryState } from 'nuqs';
2020

2121
import type {
2222
DateRangeType,
@@ -26,7 +26,7 @@ import type {
2626
TableFilterFieldFotmat,
2727
TableFilterOperator,
2828
} from '@/shared';
29-
import { client } from '@/shared';
29+
import { client, TableFilterOperators } from '@/shared';
3030

3131
import { env } from '@/env';
3232

@@ -86,7 +86,11 @@ const useFeedbackQueryConverter = (input: {
8686
}) => {
8787
const { projectId, filterFields } = input;
8888

89-
const [operator, setOperator] = useState<TableFilterOperator>('AND');
89+
const [operator, setOperator] = useQueryState<TableFilterOperator>(
90+
'operator',
91+
parseAsStringLiteral(TableFilterOperators).withDefault('AND'),
92+
);
93+
9094
const [queries, setQueries] = useQueryState<SearchQuery[]>(
9195
'queries',
9296
createParser({
@@ -122,7 +126,7 @@ const useFeedbackQueryConverter = (input: {
122126

123127
const onChangeDateRange = useCallback(async (value: DateRangeType) => {
124128
if (!value) return;
125-
console.log('value: ', value);
129+
126130
await setDefaultQueries([
127131
{
128132
key: 'createdAt',
@@ -162,11 +166,11 @@ const useFeedbackQueryConverter = (input: {
162166
{ key: 'createdAt', value: DEFAULT_DATE_RANGE, condition: 'BETWEEN' },
163167
]);
164168
await setQueries([]);
165-
setOperator('AND');
169+
await setOperator('AND');
166170
return;
167171
}
168172

169-
setOperator(operator);
173+
await setOperator(operator);
170174
await setQueries(result);
171175
},
172176
[dateRange],

apps/web/src/entities/feedback/ui/feedback-cell.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,11 @@
1515
*/
1616
import { memo } from 'react';
1717
import dayjs from 'dayjs';
18+
import Linkify from 'linkify-react';
1819

1920
import { Badge } from '@ufb/react';
2021

21-
import {
22-
DATE_TIME_FORMAT,
23-
ExpandableText,
24-
ImagePreviewButton,
25-
linkify,
26-
} from '@/shared';
22+
import { DATE_TIME_FORMAT, ExpandableText, ImagePreviewButton } from '@/shared';
2723
import type { FieldInfo } from '@/entities/field';
2824

2925
interface IProps {
@@ -73,7 +69,20 @@ const FeedbackCell: React.FC<IProps> = memo((props) => {
7369
{field.format === 'images' && (
7470
<ImagePreviewButton urls={value as string[]} />
7571
)}
76-
{field.format === 'text' && linkify(value as string)}
72+
{field.format === 'text' && (
73+
<Linkify
74+
options={{
75+
className: 'text-blue-500 underline',
76+
target: '_blank',
77+
rel: 'noopener noreferrer',
78+
attributes: {
79+
onClick: (e: React.MouseEvent) => e.stopPropagation(),
80+
},
81+
}}
82+
>
83+
{value as string | undefined}
84+
</Linkify>
85+
)}
7786
{field.format === 'keyword' && value}
7887
{field.format === 'number' && value}
7988
</>

apps/web/src/entities/user/ui/user-management-table.ui.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ const UserManagementTable: React.FC<IProps> = ({ createButton }) => {
145145
setRows(userData?.items ?? []);
146146
setPageCount(userData?.meta.totalPages ?? 0);
147147
setRowCount(userData?.meta.totalItems ?? 0);
148+
table.resetRowSelection();
148149
}, [userData, pagination, isLoading]);
149150

150151
useEffect(() => {
@@ -189,6 +190,7 @@ const UserManagementTable: React.FC<IProps> = ({ createButton }) => {
189190
<div className="flex items-center justify-between">
190191
<div className="flex items-center gap-2">
191192
<TableFilterPopover
193+
operator={operator}
192194
filterFields={[
193195
{
194196
key: 'email',

apps/web/src/entities/user/ui/user-profile-setting.ui.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ const UserProfileSetting = () => {
4545
resolver: zodResolver(userProfileSchema),
4646
});
4747

48-
const { data, refetch, isRefetching } = useOAIQuery({
48+
const { data, refetch } = useOAIQuery({
4949
path: '/api/admin/users/{id}',
5050
variables: { id: user?.id ?? 0 },
51+
queryOptions: { refetchOnWindowFocus: false },
5152
});
5253

5354
const { mutate: updateProfile, isPending: isPendingUpdateProfile } =
@@ -77,7 +78,7 @@ const UserProfileSetting = () => {
7778

7879
useEffect(() => {
7980
methods.reset(data);
80-
}, [data, isRefetching]);
81+
}, [data]);
8182

8283
useWarnIfUnsavedChanges(methods.formState.isDirty);
8384

apps/web/src/entities/user/user.schema.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,15 @@ export const changePasswordSchema = z
6969
path: ['confirmNewPassword'],
7070
},
7171
)
72+
.refine(({ newPassword }) => /[A-Za-z]/.test(newPassword), {
73+
message: 'must contain at least one letter.',
74+
path: ['newPassword'],
75+
})
7276
.refine(
73-
({ newPassword }) => /[a-zA-Z!@#$%^&*(),.?":{}|<>]/.test(newPassword),
77+
({ newPassword }) =>
78+
/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]/.test(newPassword),
7479
{
75-
message: 'must contain at least one letter or special character',
80+
message: 'must contain at least one special character.',
7681
path: ['newPassword'],
7782
},
7883
)
@@ -92,10 +97,17 @@ export const invitedUserSignupSchema = z
9297
message: 'must equal Password',
9398
path: ['confirmPassword'],
9499
})
95-
.refine(({ password }) => /[a-zA-Z!@#$%^&*(),.?":{}|<>]/.test(password), {
96-
message: 'must contain at least one letter or special character',
100+
.refine(({ password }) => /[A-Za-z]/.test(password), {
101+
message: 'must contain at least one letter.',
97102
path: ['password'],
98103
})
104+
.refine(
105+
({ password }) => /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]/.test(password),
106+
{
107+
message: 'Password must contain at least one special character.',
108+
path: ['password'],
109+
},
110+
)
99111
.refine(({ password }) => !/(.)\1/.test(password), {
100112
message: 'must not contain consecutive identical characters',
101113
path: ['password'],

0 commit comments

Comments
 (0)