Skip to content

Commit

Permalink
#1295 "Project list" widget
Browse files Browse the repository at this point in the history
  • Loading branch information
dcoraboeuf committed Jun 17, 2024
1 parent 6e95a56 commit 533db42
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.nemerosa.ontrack.model.dashboards.widgets

import org.springframework.stereotype.Component

@Component
class ProjectListWidget : AbstractWidget<ProjectListWidget.ProjectListWidgetConfig>(
key = "home/ProjectList",
name = "Project list",
description = "Fixed list of projects, suitable to easily a list of projects in a dashboard.",
defaultConfig = ProjectListWidgetConfig(),
preferredHeight = 6,
) {

data class ProjectListWidgetConfig(
val projectNames: List<String> = emptyList(),
) : WidgetConfig

}
1 change: 0 additions & 1 deletion ontrack-web-core/components/projects/ProjectList.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {Space} from "antd";
import BranchRow from "@components/branches/BranchRow";
import ProjectRow from "@components/projects/ProjectRow";

export default function ProjectList({projects}) {
Expand Down
5 changes: 4 additions & 1 deletion ontrack-web-core/components/projects/SelectProject.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export default function SelectProject({
value, onChange,
placeholder = "Project name",
idAsValue = false,
multiple = false,
width = '16em',
}) {

const client = useGraphQLClient()
Expand Down Expand Up @@ -66,8 +68,9 @@ export default function SelectProject({
label: d.name,
}))}
style={{
width: '16em',
width: width,
}}
mode={multiple ? "multiple" : undefined}
/>
</>
)
Expand Down
27 changes: 27 additions & 0 deletions ontrack-web-core/components/projects/SimpleProjectList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Empty, Space, Typography} from "antd";
import RowTag from "@components/common/RowTag";
import ProjectBox from "@components/projects/ProjectBox";

export default function SimpleProjectList({projects, emptyText}) {
return (
<>
{
projects && projects.length > 0 &&
<Space direction="horizontal" size={16} wrap>
{
projects.map(project => <RowTag key={project.id}>
<ProjectBox project={project}/>
</RowTag>
)
}
</Space>
}
{
(!projects || projects.length === 0) && <Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={<Typography.Text>{emptyText}</Typography.Text>}
/>
}
</>
)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import {useContext, useEffect, useState} from "react";
import RowTag from "@components/common/RowTag";
import ProjectBox from "@components/projects/ProjectBox";
import {Empty, Space, Typography} from "antd";
import {useEventForRefresh} from "@components/common/EventsContext";
import {useGraphQLClient} from "@components/providers/ConnectionContextProvider";
import {gql} from "graphql-request";
import {gqlDecorationFragment} from "@components/services/fragments";
import {DashboardWidgetCellContext} from "@components/dashboards/DashboardWidgetCellContextProvider";
import PaddedContent from "@components/common/PaddedContent";
import SimpleProjectList from "@components/projects/SimpleProjectList";

export default function LastActiveProjectsWidget({count}) {

Expand Down Expand Up @@ -45,31 +43,18 @@ export default function LastActiveProjectsWidget({count}) {

return (
<PaddedContent>
{
projects && projects.length > 0 &&
<Space direction="horizontal" size={16} wrap>
{
projects.map(project => <RowTag key={project.id}>
<ProjectBox project={project}/>
</RowTag>
)
}
</Space>
}
{
(!projects || projects.length === 0) && <Empty
image={Empty.PRESENTED_IMAGE_SIMPLE}
description={
<Typography.Text>
No project has been created in Ontrack yet.
You can start <a
href="https://static.nemerosa.net/ontrack/release/latest/docs/doc/index.html#feeding">feeding
information</a> in Ontrack
automatically from your CI engine, using its API or other means.
</Typography.Text>
}
/>
}
<SimpleProjectList
projects={projects}
emptyText={
<>
No project has been created in Ontrack yet.
You can start <a
href="https://static.nemerosa.net/ontrack/release/latest/docs/doc/index.html#feeding">feeding
information</a> in Ontrack
automatically from your CI engine, using its API or other means.
</>
}
/>
</PaddedContent>
)
}
78 changes: 78 additions & 0 deletions ontrack-web-core/components/widgets/home/ProjectListWidget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {gql} from "graphql-request";
import React, {useContext, useEffect, useState} from "react";
import {DashboardWidgetCellContext} from "@components/dashboards/DashboardWidgetCellContextProvider";
import {useGraphQLClient} from "@components/providers/ConnectionContextProvider";
import PaddedContent from "@components/common/PaddedContent";
import SimpleProjectList from "@components/projects/SimpleProjectList";
import {Skeleton} from "antd";
import {gqlDecorationFragment} from "@components/services/fragments";

export default function ProjectListWidget({projectNames}) {

const client = useGraphQLClient()
const [loading, setLoading] = useState(true)
const [projects, setProjects] = useState([])

const {setTitle} = useContext(DashboardWidgetCellContext)
setTitle("Project list")

const fetchProject = async (name) => {
const data = await client.request(
gql`
query GetProjectByName($name: String!) {
projects(name: $name) {
id
name
favourite
decorations {
...decorationContent
}
}
}
${gqlDecorationFragment}
`,
{name}
)
const projects = data.projects
if (projects.length > 0) {
return projects[0]
} else {
return null
}
}

useEffect(() => {
if (client) {

const fetchProjects = async () => {
setLoading(true)
try {
const projectPromises = projectNames.map(name => fetchProject(name))
const projectsData = await Promise.all(projectPromises)
setProjects(projectsData.filter(it => it !== null))
} finally {
setLoading(false)
}
}

// noinspection JSIgnoredPromiseFromCall
fetchProjects()
}
}, [client, projectNames]);

return (
<PaddedContent>
<Skeleton loading={loading} active>
<SimpleProjectList
projects={projects}
emptyText={
<>
No project has been selected.
</>
}
/>
</Skeleton>
</PaddedContent>
)
}
27 changes: 27 additions & 0 deletions ontrack-web-core/components/widgets/home/ProjectListWidgetForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {useContext} from "react";
import {Form} from "antd";
import SelectProject from "@components/projects/SelectProject";
import {DashboardWidgetCellContext} from "@components/dashboards/DashboardWidgetCellContextProvider";

export default function ProjectListWidgetForm({projectNames}) {

const {widgetEditionForm} = useContext(DashboardWidgetCellContext)

return (
<>
<Form
layout="vertical"
form={widgetEditionForm}
>
<Form.Item
name="projectNames"
label="Projects"
initialValue={projectNames}
extra="List of projects to display"
>
<SelectProject multiple={true} width="100%"/>
</Form.Item>
</Form>
</>
)
}

0 comments on commit 533db42

Please sign in to comment.