diff --git a/changes/issue-11345-grey-out-unusable-checkbox b/changes/issue-11345-grey-out-unusable-checkbox
new file mode 100644
index 0000000000..27b37d6f0f
--- /dev/null
+++ b/changes/issue-11345-grey-out-unusable-checkbox
@@ -0,0 +1 @@
+- Grey out unusable select all queries checkbox
diff --git a/frontend/components/icons/Query.tsx b/frontend/components/icons/Query.tsx
new file mode 100644
index 0000000000..2c84eb871f
--- /dev/null
+++ b/frontend/components/icons/Query.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import { COLORS, Colors } from "styles/var/colors";
+import { ICON_SIZES, IconSizes } from "styles/var/icon_sizes";
+
+interface IQuery {
+ color?: Colors;
+ size?: IconSizes;
+}
+const Query = ({ color = "core-fleet-blue", size = "medium" }: IQuery) => {
+ return (
+
+ );
+};
+
+export default Query;
diff --git a/frontend/components/icons/index.ts b/frontend/components/icons/index.ts
index 09a6df9f64..578fbb73d8 100644
--- a/frontend/components/icons/index.ts
+++ b/frontend/components/icons/index.ts
@@ -18,6 +18,7 @@ import ExternalLink from "./ExternalLink";
import Issue from "./Issue";
import Plus from "./Plus";
import PremiumFeature from "./PremiumFeature";
+import Query from "./Query";
import LowDiskSpaceHosts from "./LowDiskSpaceHosts";
import MissingHosts from "./MissingHosts";
@@ -80,6 +81,7 @@ export const ICON_MAP = {
lightbulb: Lightbulb,
issue: Issue,
plus: Plus,
+ query: Query,
clipboard: Clipboard,
eye: Eye,
pencil: Pencil,
diff --git a/frontend/pages/queries/ManageQueriesPage/_styles.scss b/frontend/pages/queries/ManageQueriesPage/_styles.scss
index af29c3c58f..062bde61f3 100644
--- a/frontend/pages/queries/ManageQueriesPage/_styles.scss
+++ b/frontend/pages/queries/ManageQueriesPage/_styles.scss
@@ -130,6 +130,15 @@
tbody {
.name__cell {
max-width: $col-lg;
+
+ .children-wrapper {
+ display: flex;
+ gap: $pad-xsmall;
+
+ .observer-can-run-tooltip {
+ font-weight: $regular;
+ }
+ }
}
@media (max-width: $break-990) {
diff --git a/frontend/pages/queries/ManageQueriesPage/components/QueriesTable/QueriesTableConfig.tsx b/frontend/pages/queries/ManageQueriesPage/components/QueriesTable/QueriesTableConfig.tsx
index 45cbb67568..c7c5e6ac51 100644
--- a/frontend/pages/queries/ManageQueriesPage/components/QueriesTable/QueriesTableConfig.tsx
+++ b/frontend/pages/queries/ManageQueriesPage/components/QueriesTable/QueriesTableConfig.tsx
@@ -11,6 +11,7 @@ import { IQuery } from "interfaces/query";
import { IUser } from "interfaces/user";
import { addGravatarUrlToResource } from "utilities/helpers";
+import Icon from "components/Icon";
import Avatar from "components/Avatar";
import Checkbox from "components/forms/fields/Checkbox";
import LinkCell from "components/TableContainer/DataTable/LinkCell/LinkCell";
@@ -101,13 +102,41 @@ const generateTableHeaders = ({
/>
),
accessor: "name",
- Cell: (cellProps: ICellProps): JSX.Element => (
-
- ),
+ Cell: (cellProps: ICellProps): JSX.Element => {
+ console.log("cellProps.row.original", cellProps.row.original);
+ return (
+
+ {cellProps.cell.value}
+ {!isOnlyObserver && cellProps.row.original.observer_can_run && (
+ <>
+
+
+
+
+ Observers can run this query.
+
+ >
+ )}
+ >
+ }
+ path={PATHS.EDIT_QUERY(cellProps.row.original)}
+ />
+ );
+ },
sortType: "caseInsensitive",
},
{
@@ -201,9 +230,24 @@ const generateTableHeaders = ({
toggleRowSelected,
} = cellProps;
const { checked, indeterminate } = getToggleAllRowsSelectedProps();
+
+ const disableToggleAllRowsSelected = () => {
+ /* Team admin or team maintainer can only delete queries they authored
+ If team admin or team maintainer authored 0 queries, disable select all queries for deletion */
+ if (isAnyTeamMaintainerOrTeamAdmin) {
+ return (
+ rows.filter(
+ (r: IQueryRow) => r.original.author_id === currentUser.id
+ ).length === 0
+ );
+ }
+ return false;
+ };
+
const checkboxProps = {
value: checked,
indeterminate,
+ disabled: disableToggleAllRowsSelected(), // Disable select all if all rows are disabled
onChange: () => {
if (!isAnyTeamMaintainerOrTeamAdmin) {
toggleAllRowsSelected();