Skip to content

[dashboard] address lint warnings #8725

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ ports:
onOpen: ignore
- port: 9229
onOpen: ignore
# Go proxy
# Go proxy
- port: 9999
onOpen: ignore
- port: 13001
onOpen: ignore
# Werft
# Werft
- port: 7777
onOpen: ignore
# Dev Theia
# Dev Theia
- port: 13444
tasks:
- name: Add Harvester kubeconfig
Expand Down Expand Up @@ -56,3 +56,5 @@ vscode:
- timonwong.shellcheck
- vscjava.vscode-java-pack
- fwcd.kotlin
- dbaeumer.vscode-eslint
- esbenp.prettier-vscode
571 changes: 312 additions & 259 deletions components/dashboard/src/App.tsx

Large diffs are not rendered by default.

237 changes: 142 additions & 95 deletions components/dashboard/src/Login.tsx

Large diffs are not rendered by default.

396 changes: 244 additions & 152 deletions components/dashboard/src/Menu.tsx

Large diffs are not rendered by default.

113 changes: 74 additions & 39 deletions components/dashboard/src/admin/ProjectsSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,51 +21,56 @@ export default function ProjectsSearchPage() {
<PageWithSubMenu subMenu={adminMenu} title="Projects" subtitle="Search and manage all projects.">
<ProjectsSearch />
</PageWithSubMenu>
)
);
}

export function ProjectsSearch() {
const location = useLocation();
const { user } = useContext(UserContext);
const [searchTerm, setSearchTerm] = useState('');
const [searchTerm, setSearchTerm] = useState("");
const [searching, setSearching] = useState(false);
const [searchResult, setSearchResult] = useState<AdminGetListResult<Project>>({ total: 0, rows: [] });
const [currentProject, setCurrentProject] = useState<Project | undefined>(undefined);
const [currentProjectOwner, setCurrentProjectOwner] = useState<string | undefined>("");

useEffect(() => {
const projectId = location.pathname.split('/')[3];
const projectId = location.pathname.split("/")[3];
if (projectId && searchResult) {
let currentProject = searchResult.rows.find(project => project.id === projectId);
let currentProject = searchResult.rows.find((project) => project.id === projectId);
if (currentProject) {
setCurrentProject(currentProject);
} else {
getGitpodService().server.adminGetProjectById(projectId)
.then(project => setCurrentProject(project))
.catch(e => console.error(e));
getGitpodService()
.server.adminGetProjectById(projectId)
.then((project) => setCurrentProject(project))
.catch((e) => console.error(e));
}
} else {
setCurrentProject(undefined);
}
}, [location]);
}, [location, searchResult]);

useEffect(() => {
(async () => {
if (currentProject) {
if (currentProject.userId) {
const owner = await getGitpodService().server.adminGetUser(currentProject.userId);
if (owner) { setCurrentProjectOwner(owner?.name) }
if (owner) {
setCurrentProjectOwner(owner?.name);
}
}
if (currentProject.teamId) {
const owner = await getGitpodService().server.adminGetTeamById(currentProject.teamId);
if (owner) { setCurrentProjectOwner(owner?.name) }
if (owner) {
setCurrentProjectOwner(owner?.name);
}
}
}
})();
}, [currentProject])
}, [currentProject]);

if (!user || !user?.rolesOrPermissions?.includes('admin')) {
return <Redirect to="/" />
if (!user || !user?.rolesOrPermissions?.includes("admin")) {
return <Redirect to="/" />;
}

if (currentProject) {
Expand All @@ -78,43 +83,71 @@ export function ProjectsSearch() {
const result = await getGitpodService().server.adminGetProjectsBySearchTerm({
searchTerm,
limit: 50,
orderBy: 'creationTime',
orderBy: "creationTime",
offset: 0,
orderDir: "desc"
})
orderDir: "desc",
});
setSearchResult(result);
} finally {
setSearching(false);
}
}
};

return <>
<div className="pt-8 flex">
<div className="flex justify-between w-full">
<div className="flex">
<div className="py-4">
<svg className={searching ? 'animate-spin' : ''} width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M6 2a4 4 0 100 8 4 4 0 000-8zM0 6a6 6 0 1110.89 3.477l4.817 4.816a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 010 6z" fill="#A8A29E" />
</svg>
return (
<>
<div className="pt-8 flex">
<div className="flex justify-between w-full">
<div className="flex">
<div className="py-4">
<svg
className={searching ? "animate-spin" : ""}
width="16"
height="16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6 2a4 4 0 100 8 4 4 0 000-8zM0 6a6 6 0 1110.89 3.477l4.817 4.816a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 010 6z"
fill="#A8A29E"
/>
</svg>
</div>
<input
type="search"
placeholder="Search Projects"
onKeyDown={(k) => k.key === "Enter" && search()}
onChange={(v) => {
setSearchTerm(v.target.value.trim());
}}
/>
</div>
<input type="search" placeholder="Search Projects" onKeyDown={(k) => k.key === 'Enter' && search()} onChange={(v) => { setSearchTerm((v.target.value).trim()) }} />
<button disabled={searching} onClick={search}>
Search
</button>
</div>
<button disabled={searching} onClick={search}>Search</button>
</div>
</div>
<div className="flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between text-sm text-gray-400 border-t border-b border-gray-200 dark:border-gray-800 mb-2">
<div className="w-4/12">Name</div>
<div className="w-6/12">Clone URL</div>
<div className="w-2/12">Created</div>
<div className="flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between text-sm text-gray-400 border-t border-b border-gray-200 dark:border-gray-800 mb-2">
<div className="w-4/12">Name</div>
<div className="w-6/12">Clone URL</div>
<div className="w-2/12">Created</div>
</div>
{searchResult.rows.map((project) => (
<ProjectResultItem project={project} />
))}
</div>
{searchResult.rows.map(project => <ProjectResultItem project={project} />)}
</div>
</>
</>
);

function ProjectResultItem(p: { project: Project }) {
return (
<Link key={'pr-' + p.project.name} to={'/admin/projects/' + p.project.id} data-analytics='{"button_type":"sidebar_menu"}'>
<Link
key={"pr-" + p.project.name}
to={"/admin/projects/" + p.project.id}
data-analytics='{"button_type":"sidebar_menu"}'
>
<div className="rounded-xl whitespace-nowrap flex py-6 px-6 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light group">
<div className="flex flex-col w-4/12 truncate">
<div className="font-medium text-gray-800 dark:text-gray-100 truncate">{p.project.name}</div>
Expand All @@ -123,10 +156,12 @@ export function ProjectsSearch() {
<div className="text-gray-500 dark:text-gray-100 truncate">{p.project.cloneUrl}</div>
</div>
<div className="flex w-2/12 self-center">
<div className="text-sm w-full text-gray-400 truncate">{moment(p.project.creationTime).fromNow()}</div>
<div className="text-sm w-full text-gray-400 truncate">
{moment(p.project.creationTime).fromNow()}
</div>
</div>
</div>
</Link>
)
);
}
}
51 changes: 34 additions & 17 deletions components/dashboard/src/admin/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,39 +27,56 @@ export default function Settings() {
}
(async () => {
const data = await getGitpodService().server.adminGetTelemetryData();
setTelemetryData(data)
setTelemetryData(data);

const setting = await getGitpodService().server.adminGetSettings();
setAdminSettings(setting)
setAdminSettings(setting);
})();
}, []);
}, [setAdminSettings]);

if (!user || !user?.rolesOrPermissions?.includes('admin')) {
return <Redirect to="/"/>
if (!user || !user?.rolesOrPermissions?.includes("admin")) {
return <Redirect to="/" />;
}

const actuallySetTelemetryPrefs = async (value: InstallationAdminSettings) => {
await getGitpodService().server.adminUpdateSettings(value);
setAdminSettings(value);
}
};

return (
<div>
<PageWithSubMenu subMenu={adminMenu} title="Settings" subtitle="Configure settings for your Gitpod cluster.">
<PageWithSubMenu
subMenu={adminMenu}
title="Settings"
subtitle="Configure settings for your Gitpod cluster."
>
<h3>Usage Statistics</h3>
<CheckBox
title="Enable Service Ping"
desc={<span>The following usage data is sent to provide insights on how you use your Gitpod instance, so we can provide a better overall experience. <a className="gp-link" href="https://www.gitpod.io/privacy">Read our Privacy Policy</a></span>}
desc={
<span>
The following usage data is sent to provide insights on how you use your Gitpod instance, so
we can provide a better overall experience.{" "}
<a className="gp-link" href="https://www.gitpod.io/privacy">
Read our Privacy Policy
</a>
</span>
}
checked={adminSettings?.sendTelemetry ?? false}
onChange={(evt) => actuallySetTelemetryPrefs({
sendTelemetry: evt.target.checked,
})} />
<InfoBox><pre>{JSON.stringify(telemetryData, null, 2)}</pre></InfoBox>
</PageWithSubMenu >
</div >
)
onChange={(evt) =>
actuallySetTelemetryPrefs({
sendTelemetry: evt.target.checked,
})
}
/>
<InfoBox>
<pre>{JSON.stringify(telemetryData, null, 2)}</pre>
</InfoBox>
</PageWithSubMenu>
</div>
);
}

function isGitpodIo() {
return window.location.hostname === 'gitpod.io' || window.location.hostname === 'gitpod-staging.com';
}
return window.location.hostname === "gitpod.io" || window.location.hostname === "gitpod-staging.com";
}
Loading