Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3bfafe3

Browse files
1 parent43d584c commit3bfafe3

File tree

7 files changed

+161
-25
lines changed

7 files changed

+161
-25
lines changed

‎site/src/api/api.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ export class MissingBuildParameters extends Error {
400400
}
401401
}
402402

403+
exporttypeGetProvisionerJobsParams={
404+
status?:TypesGen.ProvisionerJobStatus;
405+
limit?:number;
406+
};
407+
403408
/**
404409
* This is the container for all API methods. It's split off to make it more
405410
* clear where API methods should go, but it is eventually merged into the Api
@@ -2395,9 +2400,13 @@ class ApiMethods {
23952400
returnres.data;
23962401
};
23972402

2398-
getProvisionerJobs=async(orgId:string)=>{
2403+
getProvisionerJobs=async(
2404+
orgId:string,
2405+
params:GetProvisionerJobsParams={},
2406+
)=>{
23992407
constres=awaitthis.axios.get<TypesGen.ProvisionerJob[]>(
24002408
`/api/v2/organizations/${orgId}/provisionerjobs`,
2409+
{ params},
24012410
);
24022411
returnres.data;
24032412
};

‎site/src/api/queries/organizations.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import{API}from"api/api";
1+
import{API,typeGetProvisionerJobsParams}from"api/api";
22
importtype{
33
CreateOrganizationRequest,
44
GroupSyncSettings,
55
PaginatedMembersRequest,
66
PaginatedMembersResponse,
7+
ProvisionerJobStatus,
78
RoleSyncSettings,
89
UpdateOrganizationRequest,
910
}from"api/typesGenerated";
@@ -241,16 +242,18 @@ export const patchRoleSyncSettings = (
241242
};
242243
};
243244

244-
exportconstprovisionerJobQueryKey=(orgId:string)=>[
245-
"organization",
246-
orgId,
247-
"provisionerjobs",
248-
];
245+
exportconstprovisionerJobsQueryKey=(
246+
orgId:string,
247+
params:GetProvisionerJobsParams={},
248+
)=>["organization",orgId,"provisionerjobs",params];
249249

250-
exportconstprovisionerJobs=(orgId:string)=>{
250+
exportconstprovisionerJobs=(
251+
orgId:string,
252+
params:GetProvisionerJobsParams={},
253+
)=>{
251254
return{
252-
queryKey:provisionerJobQueryKey(orgId),
253-
queryFn:()=>API.getProvisionerJobs(orgId),
255+
queryKey:provisionerJobsQueryKey(orgId,params),
256+
queryFn:()=>API.getProvisionerJobs(orgId,params),
254257
};
255258
};
256259

‎site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import{API}from"api/api";
22
import{
33
getProvisionerDaemonsKey,
4-
provisionerJobQueryKey,
4+
provisionerJobsQueryKey,
55
}from"api/queries/organizations";
66
importtype{ProvisionerJob}from"api/typesGenerated";
77
import{ConfirmDialog}from"components/Dialogs/ConfirmDialog/ConfirmDialog";
@@ -28,7 +28,7 @@ export const CancelJobConfirmationDialog: FC<
2828
mutationFn:cancelProvisionerJob,
2929
onSuccess:()=>{
3030
queryClient.invalidateQueries(
31-
provisionerJobQueryKey(job.organization_id),
31+
provisionerJobsQueryKey(job.organization_id),
3232
);
3333
queryClient.invalidateQueries(
3434
getProvisionerDaemonsKey(job.organization_id,job.tags),

‎site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,20 @@ export const JobRow: FC<JobRowProps> = ({ job }) => {
5252
<Badgesize="sm">{job.type}</Badge>
5353
</TableCell>
5454
<TableCell>
55-
<divclassName="flex items-center gap-1 whitespace-nowrap">
56-
<Avatar
57-
variant="icon"
58-
src={metadata.template_icon}
59-
fallback={
60-
metadata.template_display_name||metadata.template_name
61-
}
62-
/>
63-
{metadata.template_display_name||metadata.template_name}
64-
</div>
55+
{job.metadata.template_name!=="" ?(
56+
<divclassName="flex items-center gap-1 whitespace-nowrap">
57+
<Avatar
58+
variant="icon"
59+
src={metadata.template_icon}
60+
fallback={
61+
metadata.template_display_name||metadata.template_name
62+
}
63+
/>
64+
{metadata.template_display_name||metadata.template_name}
65+
</div>
66+
) :(
67+
<span>-</span>
68+
)}
6569
</TableCell>
6670
<TableCell>
6771
<TruncateTagstags={job.tags}/>

‎site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,39 @@
1+
importtype{GetProvisionerJobsParams}from"api/api";
12
import{provisionerJobs}from"api/queries/organizations";
3+
importtype{ProvisionerJobStatus}from"api/typesGenerated";
24
import{useOrganizationSettings}from"modules/management/OrganizationSettingsLayout";
35
importtype{FC}from"react";
46
import{useQuery}from"react-query";
7+
import{useSearchParams}from"react-router-dom";
58
importOrganizationProvisionerJobsPageViewfrom"./OrganizationProvisionerJobsPageView";
69

710
constOrganizationProvisionerJobsPage:FC=()=>{
811
const{ organization}=useOrganizationSettings();
12+
const[searchParams,setSearchParams]=useSearchParams();
13+
constfilter={
14+
status:searchParams.get("status")||"",
15+
};
16+
constqueryParams={
17+
...filter,
18+
limit:100,
19+
}asGetProvisionerJobsParams;
920
const{
1021
data:jobs,
1122
isLoadingError,
1223
refetch,
1324
}=useQuery({
14-
...provisionerJobs(organization?.id||""),
25+
...provisionerJobs(organization?.id||"",queryParams),
1526
enabled:organization!==undefined,
1627
});
1728

1829
return(
1930
<OrganizationProvisionerJobsPageView
2031
jobs={jobs}
32+
filter={filter}
2133
organization={organization}
2234
error={isLoadingError}
2335
onRetry={refetch}
36+
onFilterChange={setSearchParams}
2437
/>
2538
);
2639
};

‎site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
importtype{Meta,StoryObj}from"@storybook/react";
22
import{expect,fn,userEvent,waitFor,within}from"@storybook/test";
33
importtype{ProvisionerJob}from"api/typesGenerated";
4+
import{useState}from"react";
45
import{MockOrganization,MockProvisionerJob}from"testHelpers/entities";
56
import{daysAgo}from"utils/time";
67
importOrganizationProvisionerJobsPageViewfrom"./OrganizationProvisionerJobsPageView";
@@ -20,6 +21,7 @@ const meta: Meta<typeof OrganizationProvisionerJobsPageView> = {
2021
args:{
2122
organization:MockOrganization,
2223
jobs:MockProvisionerJobs,
24+
filter:{status:""},
2325
onRetry:fn(),
2426
},
2527
};
@@ -75,3 +77,35 @@ export const Empty: Story = {
7577
jobs:[],
7678
},
7779
};
80+
81+
exportconstOnFilter:Story={
82+
render:functionFilterWithState({ ...args}){
83+
const[jobs,setJobs]=useState<ProvisionerJob[]>([]);
84+
const[filter,setFilter]=useState({status:"pending"});
85+
consthandleFilterChange=(newFilter:{status:string})=>{
86+
setFilter(newFilter);
87+
constfilteredJobs=MockProvisionerJobs.filter((job)=>
88+
newFilter.status ?job.status===newFilter.status :true,
89+
);
90+
setJobs(filteredJobs);
91+
};
92+
93+
return(
94+
<OrganizationProvisionerJobsPageView
95+
{...args}
96+
filter={filter}
97+
jobs={jobs}
98+
onFilterChange={handleFilterChange}
99+
/>
100+
);
101+
},
102+
play:async({ canvasElement})=>{
103+
constcanvas=within(canvasElement);
104+
conststatusFilter=canvas.getByTestId("status-filter");
105+
awaituserEvent.click(statusFilter);
106+
107+
constbody=within(canvasElement.ownerDocument.body);
108+
constoption=awaitbody.findByRole("option",{name:"succeeded"});
109+
awaituserEvent.click(option);
110+
},
111+
};

‎site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
1-
importtype{Organization,ProvisionerJob}from"api/typesGenerated";
1+
importtype{
2+
Organization,
3+
ProvisionerJob,
4+
ProvisionerJobStatus,
5+
}from"api/typesGenerated";
26
import{Button}from"components/Button/Button";
37
import{EmptyState}from"components/EmptyState/EmptyState";
48
import{Link}from"components/Link/Link";
59
import{Loader}from"components/Loader/Loader";
10+
import{
11+
Select,
12+
SelectContent,
13+
SelectGroup,
14+
SelectItem,
15+
SelectTrigger,
16+
SelectValue,
17+
}from"components/Select/Select";
18+
import{
19+
StatusIndicator,
20+
StatusIndicatorDot,
21+
typeStatusIndicatorProps,
22+
}from"components/StatusIndicator/StatusIndicator";
623
import{
724
Table,
825
TableBody,
@@ -17,16 +34,45 @@ import { docs } from "utils/docs";
1734
import{pageTitle}from"utils/page";
1835
import{JobRow}from"./JobRow";
1936

37+
constvariantByStatus:Record<
38+
ProvisionerJobStatus,
39+
StatusIndicatorProps["variant"]
40+
>={
41+
succeeded:"success",
42+
failed:"failed",
43+
pending:"pending",
44+
running:"pending",
45+
canceling:"pending",
46+
canceled:"inactive",
47+
unknown:"inactive",
48+
};
49+
50+
constStatusFilters:ProvisionerJobStatus[]=[
51+
"succeeded",
52+
"pending",
53+
"running",
54+
"canceling",
55+
"canceled",
56+
"failed",
57+
"unknown",
58+
];
59+
60+
typeJobProvisionersFilter={
61+
status:string;
62+
};
63+
2064
typeOrganizationProvisionerJobsPageViewProps={
2165
jobs:ProvisionerJob[]|undefined;
2266
organization:Organization|undefined;
2367
error:unknown;
68+
filter:JobProvisionersFilter;
2469
onRetry:()=>void;
70+
onFilterChange:(filter:JobProvisionersFilter)=>void;
2571
};
2672

2773
constOrganizationProvisionerJobsPageView:FC<
2874
OrganizationProvisionerJobsPageViewProps
29-
>=({ jobs, organization, error, onRetry})=>{
75+
>=({ jobs, organization, error,filter, onFilterChange,onRetry})=>{
3076
if(!organization){
3177
return(
3278
<>
@@ -61,6 +107,33 @@ const OrganizationProvisionerJobsPageView: FC<
61107
</div>
62108
</header>
63109

110+
<div>
111+
<Select
112+
value={filter.status}
113+
onValueChange={(status)=>{
114+
onFilterChange({status:statusasProvisionerJobStatus});
115+
}}
116+
>
117+
<SelectTriggerclassName="w-[180px]"data-testid="status-filter">
118+
<SelectValueplaceholder="All statuses"/>
119+
</SelectTrigger>
120+
<SelectContent>
121+
<SelectGroup>
122+
{StatusFilters.map((status)=>(
123+
<SelectItemkey={status}value={status}>
124+
<StatusIndicatorvariant={variantByStatus[status]}>
125+
<StatusIndicatorDot/>
126+
<spanclassName="block first-letter:uppercase">
127+
{status}
128+
</span>
129+
</StatusIndicator>
130+
</SelectItem>
131+
))}
132+
</SelectGroup>
133+
</SelectContent>
134+
</Select>
135+
</div>
136+
64137
<Table>
65138
<TableHeader>
66139
<TableRow>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp