Skip to content
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

Use datatable column descriptions from server-side #215

Merged
merged 3 commits into from
Dec 3, 2024
Merged
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
44 changes: 44 additions & 0 deletions goosebit/ui/bff/common/columns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from .responses import DTColumnDescription


class DeviceColumns:
uuid = DTColumnDescription(title="UUID", data="uuid", name="uuid", searchable=True, orderable=True)
name = DTColumnDescription(title="Name", data="name", name="name", searchable=True, orderable=True)
hw_model = DTColumnDescription(title="Model", data="hw_model")
hw_revision = DTColumnDescription(title="Revision", data="hw_revision")
feed = DTColumnDescription(title="Feed", data="feed", name="feed", searchable=True, orderable=True)
sw_version = DTColumnDescription(
title="Installed Software", data="sw_version", name="sw_version", searchable=True, orderable=True
)
sw_target_version = DTColumnDescription(title="Target Software", data="sw_target_version")
update_mode = DTColumnDescription(
title="Update Mode", data="update_mode", name="update_mode", searchable=True, orderable=True
)
last_state = DTColumnDescription(
title="State", data="last_state", name="last_state", searchable=True, orderable=True
)
force_update = DTColumnDescription(title="Force Update", data="force_update")
progress = DTColumnDescription(title="Progress", data="progress")
last_ip = DTColumnDescription(title="Last IP", data="last_ip")
polling = DTColumnDescription(title="Polling", data="polling")
last_seen = DTColumnDescription(title="Last Seen", data="last_seen")


class RolloutColumns:
id = DTColumnDescription(title="ID", data="id", visible=False)
created_at = DTColumnDescription(title="Created", data="created_at", name="created_at", orderable=True)
name = DTColumnDescription(title="Name", data="name", name="name", searchable=True, orderable=True)
feed = DTColumnDescription(title="Feed", data="feed", name="feed", searchable=True, orderable=True)
sw_file = DTColumnDescription(title="Software File", data="sw_file", name="sw_file")
sw_version = DTColumnDescription(title="Software Version", data="sw_version", name="sw_version")
paused = DTColumnDescription(title="Paused", name="paused", data="paused")
success_count = DTColumnDescription(title="Success Count", data="success_count", name="success_count")
failure_count = DTColumnDescription(title="Failure Count", data="failure_count", name="failure_count")


class SoftwareColumns:
id = DTColumnDescription(title="ID", data="id", visible=False)
name = DTColumnDescription(title="Name", data="name", name="name")
version = DTColumnDescription(title="Version", data="version", name="version", searchable=True, orderable=True)
compatibility = DTColumnDescription(title="Compatibility", name="compatibility", data="compatibility")
size = DTColumnDescription(title="Size", name="size", data="size")
1 change: 1 addition & 0 deletions goosebit/ui/bff/common/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class DTColumnDescription(BaseModel):

searchable: bool | None = None
orderable: bool | None = None
visible: bool | None = None


class DTColumns(BaseModel):
Expand Down
50 changes: 23 additions & 27 deletions goosebit/ui/bff/devices/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
from goosebit.device_manager import DeviceManager, get_device
from goosebit.schema.devices import DeviceSchema
from goosebit.schema.software import SoftwareSchema
from goosebit.settings import config
from goosebit.ui.bff.common.requests import DataTableRequest
from goosebit.ui.bff.common.util import parse_datatables_query

from ..common.responses import DTColumnDescription, DTColumns
from ..common.columns import DeviceColumns
from ..common.responses import DTColumns
from . import device
from .requests import DevicesPatchRequest
from .responses import BFFDeviceResponse
Expand Down Expand Up @@ -102,31 +102,27 @@ async def devices_patch(_: Request, config: DevicesPatchRequest) -> StatusRespon
dependencies=[Security(validate_user_permissions, scopes=["device.read"])],
response_model_exclude_none=True,
)
async def devices_get_columns() -> DTColumns:
columns = []
columns.append(DTColumnDescription(title="UUID", data="uuid", name="uuid", searchable=True, orderable=True))
columns.append(DTColumnDescription(title="Name", data="name", name="name", searchable=True, orderable=True))
columns.append(DTColumnDescription(title="Model", data="hw_model"))
columns.append(DTColumnDescription(title="Revision", data="hw_revision"))
columns.append(DTColumnDescription(title="Feed", data="feed", name="feed", searchable=True, orderable=True))
columns.append(
DTColumnDescription(
title="Installed Software", data="sw_version", name="sw_version", searchable=True, orderable=True
async def devices_get_columns(request: Request) -> DTColumns:
config = request.scope["config"]
columns = list(
filter(
None,
[
DeviceColumns.uuid,
DeviceColumns.name,
DeviceColumns.hw_model,
DeviceColumns.hw_revision,
DeviceColumns.feed,
DeviceColumns.sw_version,
DeviceColumns.sw_target_version,
DeviceColumns.update_mode,
DeviceColumns.last_state,
DeviceColumns.force_update,
DeviceColumns.progress,
DeviceColumns.last_ip if config.track_device_ip else None,
DeviceColumns.polling,
DeviceColumns.last_seen,
],
)
)
columns.append(DTColumnDescription(title="Target Software", data="sw_target_version"))
columns.append(
DTColumnDescription(
title="Update Mode", data="update_mode", name="update_mode", searchable=True, orderable=True
)
)
columns.append(
DTColumnDescription(title="State", data="last_state", name="last_state", searchable=True, orderable=True)
)
columns.append(DTColumnDescription(title="Force Update", data="force_update"))
columns.append(DTColumnDescription(title="Progress", data="progress"))
if config.track_device_ip:
columns.append(DTColumnDescription(title="Last IP", data="last_ip"))
columns.append(DTColumnDescription(title="Polling", data="polling"))
columns.append(DTColumnDescription(title="Last Seen", data="last_seen"))
return DTColumns(columns=columns)
27 changes: 27 additions & 0 deletions goosebit/ui/bff/rollouts/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from goosebit.ui.bff.common.requests import DataTableRequest
from goosebit.ui.bff.common.util import parse_datatables_query

from ..common.columns import RolloutColumns
from ..common.responses import DTColumns
from .responses import BFFRolloutsResponse

router = APIRouter(prefix="/rollouts")
Expand Down Expand Up @@ -52,3 +54,28 @@ def search_filter(search_value):
dependencies=[Security(validate_user_permissions, scopes=["rollout.delete"])],
name="bff_rollouts_delete",
)


@router.get(
"/columns",
dependencies=[Security(validate_user_permissions, scopes=["rollout.read"])],
response_model_exclude_none=True,
)
async def devices_get_columns() -> DTColumns:
columns = list(
filter(
None,
[
RolloutColumns.id,
RolloutColumns.created_at,
RolloutColumns.name,
RolloutColumns.feed,
RolloutColumns.sw_file,
RolloutColumns.sw_version,
RolloutColumns.paused,
RolloutColumns.success_count,
RolloutColumns.failure_count,
],
)
)
return DTColumns(columns=columns)
23 changes: 23 additions & 0 deletions goosebit/ui/bff/software/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from goosebit.ui.bff.common.util import parse_datatables_query
from goosebit.updates import create_software_update

from ..common.columns import SoftwareColumns
from ..common.responses import DTColumns
from .responses import BFFSoftwareResponse

router = APIRouter(prefix="/software")
Expand Down Expand Up @@ -94,3 +96,24 @@ async def post_update(
await create_software_update(absolute.as_uri(), temp_file)
finally:
await temp_file.unlink(missing_ok=True)


@router.get(
"/columns",
dependencies=[Security(validate_user_permissions, scopes=["software.read"])],
response_model_exclude_none=True,
)
async def devices_get_columns() -> DTColumns:
columns = list(
filter(
None,
[
SoftwareColumns.id,
SoftwareColumns.name,
SoftwareColumns.version,
SoftwareColumns.compatibility,
SoftwareColumns.size,
],
)
)
return DTColumns(columns=columns)
55 changes: 26 additions & 29 deletions goosebit/ui/static/js/rollouts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
let dataTable;

const renderFunctions = {
paused: (data, type) => {
if (type === "display") {
const color = data ? "danger" : "muted";
return `
<div class="text-${color}">
</div>
`;
}
return data;
},
created_at: (data, type) => new Date(data).toLocaleString(),
};

document.addEventListener("DOMContentLoaded", async () => {
const columnConfig = await get_request("/ui/bff/rollouts/columns");
for (const col in columnConfig.columns) {
const colDesc = columnConfig.columns[col];
const colName = colDesc.data;
if (renderFunctions[colName]) {
columnConfig.columns[col].render = renderFunctions[colName];
}
}

dataTable = new DataTable("#rollout-table", {
responsive: true,
paging: true,
Expand Down Expand Up @@ -32,37 +56,10 @@ document.addEventListener("DOMContentLoaded", async () => {
targets: "_all",
searchable: false,
orderable: false,
render: (data) => data || "-",
},
],
columns: [
{ data: "id", visible: false },
{
data: "created_at",
name: "created_at",
orderable: true,
render: (data) => new Date(data).toLocaleString(),
},
{ data: "name", name: "name", searchable: true, orderable: true },
{ data: "feed", name: "feed", searchable: true, orderable: true },
{ data: "sw_file" },
{ data: "sw_version" },
{
data: "paused",
render: (data, type) => {
if (type === "display") {
const color = data ? "danger" : "muted";
return `
<div class="text-${color}">
</div>
`;
}
return data;
},
},
{ data: "success_count" },
{ data: "failure_count" },
],
columns: columnConfig.columns,
layout: {
top1Start: {
buttons: [],
Expand Down
Loading
Loading