@flamingo-stack/openframe-frontend-core 0.0.842 → 0.0.844
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/export-map.json +1 -1
- package/dist/{chunk-2HRQU4ZL.cjs → chunk-7ERU4NGF.cjs} +10 -10
- package/dist/{chunk-RAFWT3WG.cjs → chunk-B4FUDHRE.cjs} +24 -24
- package/dist/{chunk-WOYARKPQ.cjs → chunk-C2X73N3E.cjs} +7 -7
- package/dist/{chunk-GQJXOX5S.cjs → chunk-EGOCAIZJ.cjs} +158 -86
- package/dist/{chunk-IVM35OAW.cjs → chunk-GBB7NLN7.cjs} +3 -3
- package/dist/{chunk-IVS23CAK.cjs → chunk-IUWCOK3X.cjs} +3 -3
- package/dist/{chunk-7UZYI4GV.cjs → chunk-KSOBM66X.cjs} +2 -2
- package/dist/{chunk-3ONBCAD2.cjs → chunk-KSPMB4GV.cjs} +22 -33
- package/dist/{chunk-CQQRGM6D.cjs → chunk-M7QI23GE.cjs} +31 -31
- package/dist/{chunk-SMZWXY4X.cjs → chunk-QKZQ5Q6E.cjs} +6 -1
- package/dist/{chunk-ZOWAYKDN.cjs → chunk-SVI3AB3A.cjs} +3 -3
- package/dist/{chunk-YNKXXDOI.cjs → chunk-WUJGPHF2.cjs} +4 -4
- package/dist/{cloud-tenants-U6Y2UZVF.cjs → cloud-tenants-5C32YDIE.cjs} +2 -2
- package/dist/components/case-studies/index.cjs +11 -11
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/docs/index.cjs +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/features/devices/device-unread-indicator.d.ts +6 -0
- package/dist/components/features/devices/device-unread-indicator.d.ts.map +1 -0
- package/dist/components/features/devices/device-unread-indicator.js +12 -0
- package/dist/components/features/devices/devices-grid.d.ts.map +1 -1
- package/dist/components/features/devices/devices-grid.js +5 -1
- package/dist/components/features/devices/devices-table-columns.d.ts.map +1 -1
- package/dist/components/features/devices/devices-table-columns.js +3 -1
- package/dist/components/features/devices/devices-view-config.d.ts +6 -4
- package/dist/components/features/devices/devices-view-config.d.ts.map +1 -1
- package/dist/components/features/devices/index.d.ts +1 -0
- package/dist/components/features/devices/index.d.ts.map +1 -1
- package/dist/components/features/devices/index.js +2 -0
- package/dist/components/features/devices/types.d.ts +2 -0
- package/dist/components/features/devices/types.d.ts.map +1 -1
- package/dist/components/features/index.cjs +4 -2
- package/dist/components/features/software/update-settings-fields.d.ts.map +1 -1
- package/dist/components/features/software/update-settings-fields.js +1 -1
- package/dist/components/help-center-pages/index.cjs +46 -46
- package/dist/components/index.cjs +25 -17
- package/dist/components/meeting-scheduler/index.cjs +20 -20
- package/dist/components/navigation/count-pill.d.ts +10 -0
- package/dist/components/navigation/count-pill.d.ts.map +1 -0
- package/dist/components/navigation/count-pill.js +18 -0
- package/dist/components/navigation/index.cjs +9 -3
- package/dist/components/navigation/index.d.ts +4 -0
- package/dist/components/navigation/index.d.ts.map +1 -1
- package/dist/components/navigation/index.js +5 -0
- package/dist/components/navigation/navigation-sidebar-grouped.d.ts.map +1 -1
- package/dist/components/navigation/navigation-sidebar-grouped.js +1 -12
- package/dist/components/navigation/unread-notifications-indicator.d.ts +19 -0
- package/dist/components/navigation/unread-notifications-indicator.d.ts.map +1 -0
- package/dist/components/navigation/unread-notifications-indicator.js +45 -0
- package/dist/components/onboarding-guides/index.cjs +3 -3
- package/dist/components/product-demo/fixtures/devices.d.ts.map +1 -1
- package/dist/components/product-demo/fixtures/devices.js +6 -1
- package/dist/components/product-demo/index.cjs +11 -11
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/ui/index.cjs +2 -2
- package/dist/{devices-HB4GEMJH.cjs → devices-F2ENCTJM.cjs} +5 -5
- package/dist/index.cjs +11 -3
- package/dist/{knowledge-I53Z6DV7.cjs → knowledge-ZNUNREKL.cjs} +2 -2
- package/dist/{logs-SFLAZIQG.cjs → logs-DHZFCX2I.cjs} +9 -9
- package/dist/{policies-EIAGQO6T.cjs → policies-2FKRLSOC.cjs} +6 -6
- package/dist/{scripts-SNJ4UVRF.cjs → scripts-J3J7XCT4.cjs} +7 -7
- package/dist/{software-update-AZFRUC5N.cjs → software-update-AIQHLJ5O.cjs} +7 -7
- package/package.json +1 -1
- package/src/components/features/devices/device-unread-indicator.tsx +14 -0
- package/src/components/features/devices/devices-grid.tsx +9 -1
- package/src/components/features/devices/devices-table-columns.tsx +3 -0
- package/src/components/features/devices/devices-view-config.tsx +6 -4
- package/src/components/features/devices/index.ts +1 -0
- package/src/components/features/devices/types.ts +2 -0
- package/src/components/features/software/update-settings-fields.tsx +19 -16
- package/src/components/navigation/count-pill.tsx +25 -0
- package/src/components/navigation/index.ts +4 -0
- package/src/components/navigation/navigation-sidebar-grouped.tsx +1 -14
- package/src/components/navigation/unread-notifications-indicator.tsx +69 -0
- package/src/components/product-demo/fixtures/devices.ts +7 -0
|
@@ -8,7 +8,7 @@ var _chunkLHV2R6QUcjs = require('./chunk-LHV2R6QU.cjs');
|
|
|
8
8
|
var _chunkFDZOE5TLcjs = require('./chunk-FDZOE5TL.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkEGOCAIZJcjs = require('./chunk-EGOCAIZJ.cjs');
|
|
12
12
|
require('./chunk-WCK5T3UD.cjs');
|
|
13
13
|
require('./chunk-744JXTDP.cjs');
|
|
14
14
|
require('./chunk-NMLNZCK2.cjs');
|
|
@@ -1908,7 +1908,7 @@ function KnowledgeScreen(_props) {
|
|
|
1908
1908
|
const cast = _chunkLHV2R6QUcjs.useProductDemoCast.call(void 0, );
|
|
1909
1909
|
const fixture = _react.useMemo.call(void 0, () => buildKnowledgeFixture(cast), [cast]);
|
|
1910
1910
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1911
|
-
|
|
1911
|
+
_chunkEGOCAIZJcjs.KnowledgeBaseArticleView,
|
|
1912
1912
|
{
|
|
1913
1913
|
...fixture.article,
|
|
1914
1914
|
content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWPMJUYW3cjs.SimpleMarkdownRenderer, { content: fixture.content, textSize: "compact" })
|
|
@@ -15,7 +15,7 @@ var _chunkFDZOE5TLcjs = require('./chunk-FDZOE5TL.cjs');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _chunkEGOCAIZJcjs = require('./chunk-EGOCAIZJ.cjs');
|
|
19
19
|
require('./chunk-WCK5T3UD.cjs');
|
|
20
20
|
require('./chunk-744JXTDP.cjs');
|
|
21
21
|
require('./chunk-NMLNZCK2.cjs');
|
|
@@ -1890,7 +1890,7 @@ function entry(logId, minutesAgo, severity, toolType, device2, summary) {
|
|
|
1890
1890
|
id: logId,
|
|
1891
1891
|
logId,
|
|
1892
1892
|
timestamp: displayTime(_chunkFDZOE5TLcjs.demoMinutesAgo.call(void 0, minutesAgo)),
|
|
1893
|
-
status: { label: severity, variant:
|
|
1893
|
+
status: { label: severity, variant: _chunkEGOCAIZJcjs.logSeverityVariant.call(void 0, severity) },
|
|
1894
1894
|
source: { name: toolType, toolType },
|
|
1895
1895
|
device: device2,
|
|
1896
1896
|
description: { title: summary }
|
|
@@ -1962,13 +1962,13 @@ var NO_FILTERS = {};
|
|
|
1962
1962
|
var ACTION_COLUMNS = ["copy", "quickView", "open"];
|
|
1963
1963
|
var BESIDE_DRAWER_HIDDEN = [...ACTION_COLUMNS, "tool", "source"];
|
|
1964
1964
|
var logHref = () => "#";
|
|
1965
|
-
var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1965
|
+
var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEGOCAIZJcjs.LogCopyIconButton, {});
|
|
1966
1966
|
function LogsScreen({ compact = false }) {
|
|
1967
1967
|
const [dock, setDock] = _react.useState.call(void 0, null);
|
|
1968
1968
|
const selected = LOGS_FIXTURE_SELECTED;
|
|
1969
1969
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full bg-ods-bg", children: [
|
|
1970
1970
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1 overflow-clip", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1971
|
-
|
|
1971
|
+
_chunkEGOCAIZJcjs.LogsPageView,
|
|
1972
1972
|
{
|
|
1973
1973
|
showHeader: false,
|
|
1974
1974
|
className: "p-[var(--spacing-system-l)]",
|
|
@@ -1976,7 +1976,7 @@ function LogsScreen({ compact = false }) {
|
|
|
1976
1976
|
onSearchChange: noop,
|
|
1977
1977
|
onOpenFilters: noop,
|
|
1978
1978
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1979
|
-
|
|
1979
|
+
_chunkEGOCAIZJcjs.LogsTableView,
|
|
1980
1980
|
{
|
|
1981
1981
|
logs: LOGS_FIXTURE_ENTRIES,
|
|
1982
1982
|
facets: LOGS_FIXTURE_FACETS,
|
|
@@ -1991,7 +1991,7 @@ function LogsScreen({ compact = false }) {
|
|
|
1991
1991
|
}
|
|
1992
1992
|
) }),
|
|
1993
1993
|
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setDock, className: "relative w-[calc(400px+var(--spacing-system-m))] shrink-0", children: dock && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkOT6P57ZScjs.AppLayoutDrawerContainerContext.Provider, { value: dock, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1994
|
-
|
|
1994
|
+
_chunkEGOCAIZJcjs.LogDrawer,
|
|
1995
1995
|
{
|
|
1996
1996
|
docked: true,
|
|
1997
1997
|
isOpen: true,
|
|
@@ -2003,12 +2003,12 @@ function LogsScreen({ compact = false }) {
|
|
|
2003
2003
|
{ label: "Log ID", value: selected.logId },
|
|
2004
2004
|
{
|
|
2005
2005
|
label: "Source",
|
|
2006
|
-
value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2006
|
+
value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEGOCAIZJcjs.ToolBadge, { toolType: _chunk4ASUUB3Acjs.normalizeToolTypeWithFallback.call(void 0, selected.source.toolType) })
|
|
2007
2007
|
},
|
|
2008
|
-
{ label: "Device", value:
|
|
2008
|
+
{ label: "Device", value: _chunkEGOCAIZJcjs.logSourceLabels.call(void 0, selected.device).deviceName }
|
|
2009
2009
|
],
|
|
2010
2010
|
deviceCard: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2011
|
-
|
|
2011
|
+
_chunkEGOCAIZJcjs.DeviceCard,
|
|
2012
2012
|
{
|
|
2013
2013
|
...LOGS_FIXTURE_DEVICE,
|
|
2014
2014
|
actions: {
|
|
@@ -10,7 +10,7 @@ var _chunkFDZOE5TLcjs = require('./chunk-FDZOE5TL.cjs');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkEGOCAIZJcjs = require('./chunk-EGOCAIZJ.cjs');
|
|
14
14
|
require('./chunk-WCK5T3UD.cjs');
|
|
15
15
|
require('./chunk-744JXTDP.cjs');
|
|
16
16
|
require('./chunk-NMLNZCK2.cjs');
|
|
@@ -1894,14 +1894,14 @@ var POLICIES = [
|
|
|
1894
1894
|
policy("policy-local-admins", "No local admins", "No everyday account is a local administrator.", false, 0)
|
|
1895
1895
|
];
|
|
1896
1896
|
var POLICIES_FIXTURE = {
|
|
1897
|
-
summary:
|
|
1897
|
+
summary: _chunkEGOCAIZJcjs.computePolicySummary.call(void 0, POLICIES),
|
|
1898
1898
|
rows: POLICIES.map((item) => ({
|
|
1899
1899
|
id: item.id,
|
|
1900
1900
|
name: item.name,
|
|
1901
1901
|
description: item.description,
|
|
1902
1902
|
critical: item.critical,
|
|
1903
1903
|
severityLabel: item.critical ? "Critical" : "Low",
|
|
1904
|
-
status:
|
|
1904
|
+
status: _chunkEGOCAIZJcjs.getPolicyTableStatus.call(void 0, item),
|
|
1905
1905
|
actions: [
|
|
1906
1906
|
{ label: "Policy Details", onClick: noop },
|
|
1907
1907
|
{ label: "Delete Policy", onClick: noop }
|
|
@@ -1915,16 +1915,16 @@ var POLICIES_FIXTURE = {
|
|
|
1915
1915
|
var _jsxruntime = require('react/jsx-runtime');
|
|
1916
1916
|
function PoliciesScreen({ compact = false }) {
|
|
1917
1917
|
const table = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1918
|
-
|
|
1918
|
+
_chunkEGOCAIZJcjs.PoliciesTable,
|
|
1919
1919
|
{
|
|
1920
1920
|
rows: POLICIES_FIXTURE.rows,
|
|
1921
1921
|
rowAsLink: true,
|
|
1922
|
-
rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1922
|
+
rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEGOCAIZJcjs.DataTable.RowCount, {}),
|
|
1923
1923
|
emptyMessage: "No policies found."
|
|
1924
1924
|
}
|
|
1925
1925
|
);
|
|
1926
1926
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-[var(--spacing-system-l)] bg-ods-bg p-[var(--spacing-system-l)]", children: [
|
|
1927
|
-
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1927
|
+
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEGOCAIZJcjs.PolicySummaryCards, { summary: POLICIES_FIXTURE.summary, now: POLICIES_FIXTURE.now }),
|
|
1928
1928
|
table
|
|
1929
1929
|
] });
|
|
1930
1930
|
}
|
|
@@ -13,7 +13,7 @@ var _chunkFDZOE5TLcjs = require('./chunk-FDZOE5TL.cjs');
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
var
|
|
16
|
+
var _chunkEGOCAIZJcjs = require('./chunk-EGOCAIZJ.cjs');
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
var _chunkWCK5T3UDcjs = require('./chunk-WCK5T3UD.cjs');
|
|
@@ -1998,8 +1998,8 @@ function buildScriptsFixture(cast) {
|
|
|
1998
1998
|
var _jsxruntime = require('react/jsx-runtime');
|
|
1999
1999
|
var WIDE_HIDDEN_COLUMNS = ["result", "open"];
|
|
2000
2000
|
var COMPACT_COLUMNS = [
|
|
2001
|
-
{ ...
|
|
2002
|
-
|
|
2001
|
+
{ ..._chunkEGOCAIZJcjs.EXECUTION_COLUMNS.machineId, width: "flex-1 min-w-0", hideAt: void 0 },
|
|
2002
|
+
_chunkEGOCAIZJcjs.EXECUTION_COLUMNS.status
|
|
2003
2003
|
];
|
|
2004
2004
|
var COMPACT_ROWS = 4;
|
|
2005
2005
|
var TOKEN_CLASS = {
|
|
@@ -2058,7 +2058,7 @@ function ScriptCodePicture({ script }) {
|
|
|
2058
2058
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-w-0 items-center justify-between gap-[var(--spacing-system-m)]", children: [
|
|
2059
2059
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWCK5T3UDcjs.TruncateText, { variant: "h6", tone: "secondary", children: `Written by ${provenance.author} \xB7 approved by ${provenance.approver}` }),
|
|
2060
2060
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2061
|
-
|
|
2061
|
+
_chunkEGOCAIZJcjs.ScriptShellBadge,
|
|
2062
2062
|
{
|
|
2063
2063
|
value: script.shellType,
|
|
2064
2064
|
className: "shrink-0 text-ods-text-secondary text-h6",
|
|
@@ -2082,7 +2082,7 @@ function ScriptsScreen({ compact = false }) {
|
|
|
2082
2082
|
return (
|
|
2083
2083
|
// Four runs of the card's row height fill the frame; the padding is what is left round them.
|
|
2084
2084
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full overflow-hidden bg-ods-bg p-[var(--spacing-system-xsf)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2085
|
-
|
|
2085
|
+
_chunkEGOCAIZJcjs.ScriptExecutionsTable,
|
|
2086
2086
|
{
|
|
2087
2087
|
rows: fixture.executions.slice(0, COMPACT_ROWS),
|
|
2088
2088
|
columns: COMPACT_COLUMNS,
|
|
@@ -2092,13 +2092,13 @@ function ScriptsScreen({ compact = false }) {
|
|
|
2092
2092
|
) })
|
|
2093
2093
|
);
|
|
2094
2094
|
}
|
|
2095
|
-
const renderOutput = (row) => row.id === fixture.openExecutionId ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2095
|
+
const renderOutput = (row) => row.id === fixture.openExecutionId ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkEGOCAIZJcjs.ScriptExecutionResult, { result: row.result, empty: "\u2014" }) : null;
|
|
2096
2096
|
return (
|
|
2097
2097
|
// The frame's tighter padding and no header row: the output opened under a run needs the height.
|
|
2098
2098
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full gap-[var(--spacing-system-m)] overflow-hidden bg-ods-bg p-[var(--spacing-system-m)]", children: [
|
|
2099
2099
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-[39%] shrink-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScriptCodePicture, { script: fixture.script }) }),
|
|
2100
2100
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2101
|
-
|
|
2101
|
+
_chunkEGOCAIZJcjs.ScriptExecutionsTable,
|
|
2102
2102
|
{
|
|
2103
2103
|
rows: fixture.executions,
|
|
2104
2104
|
hideColumns: WIDE_HIDDEN_COLUMNS,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkQKZQ5Q6Ecjs = require('./chunk-QKZQ5Q6E.cjs');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
var _chunkLHV2R6QUcjs = require('./chunk-LHV2R6QU.cjs');
|
|
@@ -15,7 +15,7 @@ var _chunkFDZOE5TLcjs = require('./chunk-FDZOE5TL.cjs');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _chunkEGOCAIZJcjs = require('./chunk-EGOCAIZJ.cjs');
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
var _chunkWCK5T3UDcjs = require('./chunk-WCK5T3UD.cjs');
|
|
@@ -1905,7 +1905,7 @@ var initialValues = {
|
|
|
1905
1905
|
timeReference: "SERVER"
|
|
1906
1906
|
};
|
|
1907
1907
|
function buildSoftwareUpdateFixture(cast) {
|
|
1908
|
-
const devices =
|
|
1908
|
+
const devices = _chunkQKZQ5Q6Ecjs.buildDevicesFixture.call(void 0, cast).devices.filter((device) => device.osType === "WINDOWS");
|
|
1909
1909
|
return {
|
|
1910
1910
|
action: "UPDATE",
|
|
1911
1911
|
package: chrome,
|
|
@@ -1925,12 +1925,12 @@ function StaticPackageField({ value }) {
|
|
|
1925
1925
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1926
1926
|
_chunkWCK5T3UDcjs.Autocomplete,
|
|
1927
1927
|
{
|
|
1928
|
-
label:
|
|
1928
|
+
label: _chunkEGOCAIZJcjs.PACKAGE_SEARCH_LABEL,
|
|
1929
1929
|
labelVariant: "large",
|
|
1930
1930
|
options: value ? [{ value: value.id, label: value.name, description: _nullishCoalesce(value.description, () => ( void 0)) }] : [],
|
|
1931
1931
|
value: _nullishCoalesce(_optionalChain([value, 'optionalAccess', _ => _.id]), () => ( null)),
|
|
1932
1932
|
onChange: noop,
|
|
1933
|
-
placeholder:
|
|
1933
|
+
placeholder: _chunkEGOCAIZJcjs.PACKAGE_SEARCH_PLACEHOLDER
|
|
1934
1934
|
}
|
|
1935
1935
|
);
|
|
1936
1936
|
}
|
|
@@ -1944,7 +1944,7 @@ function SoftwareUpdateScreen({ compact = false }) {
|
|
|
1944
1944
|
[fixture.devices, fixture.selectedIds]
|
|
1945
1945
|
);
|
|
1946
1946
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1947
|
-
|
|
1947
|
+
_chunkEGOCAIZJcjs.SoftwareActionForm,
|
|
1948
1948
|
{
|
|
1949
1949
|
action: fixture.action,
|
|
1950
1950
|
showHeader: false,
|
|
@@ -1956,7 +1956,7 @@ function SoftwareUpdateScreen({ compact = false }) {
|
|
|
1956
1956
|
initialValues: fixture.initialValues,
|
|
1957
1957
|
renderPackageSearch,
|
|
1958
1958
|
renderDevicePicker: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1959
|
-
|
|
1959
|
+
_chunkEGOCAIZJcjs.DeviceSelector,
|
|
1960
1960
|
{
|
|
1961
1961
|
devices: selected,
|
|
1962
1962
|
loading: false,
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { UnreadNotificationsIndicator } from '../../navigation/unread-notifications-indicator';
|
|
4
|
+
import { useDevicesViewConfig } from './devices-view-config';
|
|
5
|
+
import type { DeviceRow } from './types';
|
|
6
|
+
|
|
7
|
+
/** The viewer's unread notifications about a device, opening them where the host lists them. Nothing at 0. */
|
|
8
|
+
export function DeviceUnreadIndicator({ device }: { device: DeviceRow }) {
|
|
9
|
+
const { getDeviceNotificationsHref } = useDevicesViewConfig();
|
|
10
|
+
const count = device.unreadNotificationCount ?? 0;
|
|
11
|
+
return (
|
|
12
|
+
<UnreadNotificationsIndicator count={count} href={count > 0 ? getDeviceNotificationsHref?.(device) : undefined} />
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -7,6 +7,7 @@ import { DeviceCard } from '../../ui';
|
|
|
7
7
|
import { LoadingItems, useLoadingScope } from '../../ui/loading-scope';
|
|
8
8
|
import { getDeviceName } from './device-name';
|
|
9
9
|
import { getDeviceOperatingSystem, getDeviceStatusConfig } from './device-status';
|
|
10
|
+
import { DeviceUnreadIndicator } from './device-unread-indicator';
|
|
10
11
|
import { useDevicesViewConfig } from './devices-view-config';
|
|
11
12
|
import type { DeviceRow } from './types';
|
|
12
13
|
|
|
@@ -102,7 +103,14 @@ export function DevicesGrid<T extends DeviceRow = DeviceRow>({
|
|
|
102
103
|
: undefined
|
|
103
104
|
}
|
|
104
105
|
onDeviceClick={() => handleDeviceClick(device)}
|
|
105
|
-
actions={
|
|
106
|
+
actions={
|
|
107
|
+
device.unreadNotificationCount
|
|
108
|
+
? {
|
|
109
|
+
...GRID_CARD_ACTIONS,
|
|
110
|
+
detailsButton: { component: <DeviceUnreadIndicator device={device} /> },
|
|
111
|
+
}
|
|
112
|
+
: GRID_CARD_ACTIONS
|
|
113
|
+
}
|
|
106
114
|
className="h-full"
|
|
107
115
|
// One card of a read list: how many there are is the record's (the height gate counts them).
|
|
108
116
|
data-loading-item
|
|
@@ -27,6 +27,7 @@ import { getDeviceName } from './device-name';
|
|
|
27
27
|
import { getDeviceStatusConfig } from './device-status';
|
|
28
28
|
import { DEFAULT_VISIBLE_STATUSES } from './device-statuses';
|
|
29
29
|
import { DeviceTypeTile } from './device-type-tile';
|
|
30
|
+
import { DeviceUnreadIndicator } from './device-unread-indicator';
|
|
30
31
|
import { useDeviceImageUrl, useDevicesViewConfig } from './devices-view-config';
|
|
31
32
|
import type { DeviceFilters, DeviceRow } from './types';
|
|
32
33
|
|
|
@@ -341,6 +342,8 @@ export function getDeviceTableColumns<T extends DeviceRow = DeviceRow>(
|
|
|
341
342
|
<div className="min-w-0 flex-1">
|
|
342
343
|
<TruncateText>{getDeviceName(device)}</TruncateText>
|
|
343
344
|
</div>
|
|
345
|
+
{/* In the name's cell, not the open column: that one is dropped on a narrow page. */}
|
|
346
|
+
<DeviceUnreadIndicator device={device} />
|
|
344
347
|
</div>
|
|
345
348
|
);
|
|
346
349
|
},
|
|
@@ -5,14 +5,16 @@ import type { DeviceRow } from './types';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* What the device views cannot know by themselves, because it belongs to the
|
|
8
|
-
* host: where a device's page
|
|
9
|
-
* the page runs inside the mobile shell. The product
|
|
10
|
-
* every page; without a provider the views render as a
|
|
11
|
-
* image URLs used as given).
|
|
8
|
+
* host: where a device's page and its notifications live, where images are
|
|
9
|
+
* served from, and whether the page runs inside the mobile shell. The product
|
|
10
|
+
* provides it once, above every page; without a provider the views render as a
|
|
11
|
+
* picture (no links, image URLs used as given).
|
|
12
12
|
*/
|
|
13
13
|
export interface DevicesViewConfig {
|
|
14
14
|
/** The device's page. Absent: rows and cards are not links. */
|
|
15
15
|
getDeviceHref?: (device: DeviceRow) => string | undefined;
|
|
16
|
+
/** The viewer's notifications about the device. Absent: the unread indicator is a counter, not a button. */
|
|
17
|
+
getDeviceNotificationsHref?: (device: DeviceRow) => string | undefined;
|
|
16
18
|
/** A customer image's full URL from its stored path and content hash. */
|
|
17
19
|
resolveImageUrl?: (imageUrl: string | null | undefined, hash?: string | null) => string | undefined;
|
|
18
20
|
/** The page runs inside the mobile shell: options nobody can pick there are dropped. */
|
|
@@ -38,6 +38,7 @@ export {
|
|
|
38
38
|
export { DeviceTagsFilterButton } from './device-tags-filter-button';
|
|
39
39
|
export { renderDeviceTypeIcon } from './device-type-icon';
|
|
40
40
|
export { DeviceTypeTile } from './device-type-tile';
|
|
41
|
+
export { DeviceUnreadIndicator } from './device-unread-indicator';
|
|
41
42
|
export { DevicesFilterToolbar, type DevicesFilterToolbarProps } from './devices-filter-toolbar';
|
|
42
43
|
export { DevicesGrid, type DevicesGridProps } from './devices-grid';
|
|
43
44
|
export { DevicesGridFilters, type DevicesGridFiltersProps } from './devices-grid-filters';
|
|
@@ -34,6 +34,8 @@ export interface DeviceRow extends DeviceNameSource {
|
|
|
34
34
|
organizationImageUrl?: string | null;
|
|
35
35
|
organizationImageHash?: string | null;
|
|
36
36
|
tags?: DeviceTag[];
|
|
37
|
+
/** The viewer's unread notifications about this device. Absent or 0: no indicator. */
|
|
38
|
+
unreadNotificationCount?: number;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export interface DeviceFilterValue {
|
|
@@ -244,22 +244,25 @@ export function SoftwareUpdateSettingsFields({ value, onChange }: SoftwareUpdate
|
|
|
244
244
|
</div>
|
|
245
245
|
</div>
|
|
246
246
|
|
|
247
|
-
{/* Core Alert on the card surface, as a note: it
|
|
248
|
-
a
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
247
|
+
{/* Core Alert on the card surface, as a note: it comes with "Keep it auto-updated" and goes with it, since the
|
|
248
|
+
reinstall is what lets OpenFrame keep a hand-installed app updated, and a one-off update promises no more. The
|
|
249
|
+
icon sits in a span so Alert's `[&>svg]` positioning does not apply. */}
|
|
250
|
+
{value.autoUpdate && (
|
|
251
|
+
<Alert
|
|
252
|
+
role="note"
|
|
253
|
+
className="flex items-center gap-[var(--spacing-system-m)] rounded-[6px] border-ods-border bg-ods-card p-[var(--spacing-system-m)]"
|
|
254
|
+
>
|
|
255
|
+
<span className="shrink-0 text-ods-text-secondary">
|
|
256
|
+
<InfoCircleIcon size={24} color="currentColor" />
|
|
257
|
+
</span>
|
|
258
|
+
<div className="flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-xxs)]">
|
|
259
|
+
<p className="text-ods-text-primary text-h3">Apps installed by hand get reinstalled</p>
|
|
260
|
+
<p className="text-ods-text-secondary text-h6">
|
|
261
|
+
On the first update, OpenFrame reinstalls them with Winget or Brew so it can keep them updated.
|
|
262
|
+
</p>
|
|
263
|
+
</div>
|
|
264
|
+
</Alert>
|
|
265
|
+
)}
|
|
263
266
|
</section>
|
|
264
267
|
);
|
|
265
268
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../utils/cn';
|
|
4
|
+
|
|
5
|
+
export interface CountPillProps {
|
|
6
|
+
count: number;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The navigation's unread count: a 24px accent pill, widening for "99+". The grouped sidebar ends its rows with it,
|
|
12
|
+
* and a list row that counts the same notifications draws the same pill, so the two read alike.
|
|
13
|
+
*/
|
|
14
|
+
export function CountPill({ count, className }: CountPillProps) {
|
|
15
|
+
return (
|
|
16
|
+
<span
|
|
17
|
+
className={cn(
|
|
18
|
+
'flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md bg-ods-accent px-[var(--spacing-system-xxs)]',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
<span className="text-ods-text-on-accent text-h5">{count > 99 ? '99+' : count}</span>
|
|
23
|
+
</span>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -90,6 +90,10 @@ export { HeaderButton } from './header-button';
|
|
|
90
90
|
export type { HeaderButtonProps } from './header-button';
|
|
91
91
|
export { UnreadDot, UnreadCountBadge } from './unread-dot';
|
|
92
92
|
export type { UnreadDotProps, UnreadCountBadgeProps } from './unread-dot';
|
|
93
|
+
export { CountPill } from './count-pill';
|
|
94
|
+
export type { CountPillProps } from './count-pill';
|
|
95
|
+
export { UnreadNotificationsIndicator, unreadNotificationsLabel } from './unread-notifications-indicator';
|
|
96
|
+
export type { UnreadNotificationsIndicatorProps } from './unread-notifications-indicator';
|
|
93
97
|
export { NavigationItemBadge } from './navigation-item-badge';
|
|
94
98
|
export type { NavigationItemBadgeProps } from './navigation-item-badge';
|
|
95
99
|
export { TicketAlertsButton } from './ticket-alerts-button';
|
|
@@ -7,6 +7,7 @@ import type { NavigationSidebarItem } from '../../types/navigation';
|
|
|
7
7
|
import { cn } from '../../utils';
|
|
8
8
|
import { UnifiedSkeleton } from '../loading/unified-skeleton';
|
|
9
9
|
import { FloatingTooltip } from '../ui/floating-tooltip';
|
|
10
|
+
import { CountPill } from './count-pill';
|
|
10
11
|
import { NavigationItemBadge } from './navigation-item-badge';
|
|
11
12
|
import { UnreadDot } from './unread-dot';
|
|
12
13
|
|
|
@@ -133,20 +134,6 @@ interface RowStateProps {
|
|
|
133
134
|
disabled: boolean;
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
/** The count pill: 24px, widening for "99+". */
|
|
137
|
-
function CountPill({ count, className }: { count: number; className?: string }) {
|
|
138
|
-
return (
|
|
139
|
-
<span
|
|
140
|
-
className={cn(
|
|
141
|
-
'flex h-6 min-w-6 shrink-0 items-center justify-center rounded-md bg-ods-accent px-[var(--spacing-system-xxs)]',
|
|
142
|
-
className,
|
|
143
|
-
)}
|
|
144
|
-
>
|
|
145
|
-
<span className="text-ods-text-on-accent text-h5">{count > 99 ? '99+' : count}</span>
|
|
146
|
-
</span>
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
137
|
/** The row's end, flush right where every row's count sits. */
|
|
151
138
|
function RowEnd({ count }: { count: number }) {
|
|
152
139
|
return count > 0 ? <CountPill count={count} className="ml-auto" /> : null;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { MouseEvent } from 'react';
|
|
4
|
+
import { useChatRuntime } from '../../contexts/chat-runtime-context';
|
|
5
|
+
import { cn } from '../../utils/cn';
|
|
6
|
+
import { isModifierClick } from '../chat/utils/chat-nav-resolution';
|
|
7
|
+
import { executeNavigationImperative, executeNewTabNavigation } from '../chat/utils/execute-navigation';
|
|
8
|
+
import { CountPill } from './count-pill';
|
|
9
|
+
|
|
10
|
+
/** What the indicator says to a screen reader: the count, in words. */
|
|
11
|
+
export function unreadNotificationsLabel(count: number): string {
|
|
12
|
+
return `${count} unread ${count === 1 ? 'notification' : 'notifications'}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface UnreadNotificationsIndicatorProps {
|
|
16
|
+
/** The viewer's unread notifications about one item. Nothing is drawn at 0. */
|
|
17
|
+
count: number;
|
|
18
|
+
/** Where those notifications are listed. Absent: the count alone, not a button. */
|
|
19
|
+
href?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The viewer's unread notifications about one item of a list (a device, an incident), drawn with the sidebar's own
|
|
25
|
+
* count pill so a row and its section's badge read alike.
|
|
26
|
+
*
|
|
27
|
+
* A button, not a link: the row or card it sits in is usually a link itself, and a link cannot hold another
|
|
28
|
+
* (`data-no-row-click` keeps a table row from following its own). It goes through the lib's navigation executor,
|
|
29
|
+
* so the host decides how `href` opens, and a modifier click asks for a new tab as it would on a link.
|
|
30
|
+
*/
|
|
31
|
+
export function UnreadNotificationsIndicator({ count, href, className }: UnreadNotificationsIndicatorProps) {
|
|
32
|
+
const runtime = useChatRuntime();
|
|
33
|
+
if (count <= 0) return null;
|
|
34
|
+
|
|
35
|
+
const label = unreadNotificationsLabel(count);
|
|
36
|
+
|
|
37
|
+
if (!href) {
|
|
38
|
+
return (
|
|
39
|
+
<span data-loading-optional role="img" aria-label={label} className={cn('inline-flex shrink-0', className)}>
|
|
40
|
+
<CountPill count={count} />
|
|
41
|
+
</span>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const open = (event: MouseEvent) => {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
event.stopPropagation();
|
|
48
|
+
if (isModifierClick(event)) executeNewTabNavigation({ runtime, href });
|
|
49
|
+
else executeNavigationImperative({ runtime, href });
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<button
|
|
54
|
+
type="button"
|
|
55
|
+
data-loading-optional
|
|
56
|
+
data-no-row-click
|
|
57
|
+
onClick={open}
|
|
58
|
+
aria-label={label}
|
|
59
|
+
title={label}
|
|
60
|
+
className={cn(
|
|
61
|
+
'pointer-events-auto inline-flex shrink-0 rounded-md transition-opacity hover:opacity-80',
|
|
62
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus',
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
<CountPill count={count} />
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -4,6 +4,12 @@ import { type DEMO_DEVICES, DEMO_FLEET, DEMO_FLEET_SEARCH_OS, demoMinutesAgo } f
|
|
|
4
4
|
|
|
5
5
|
type DemoDevice = (typeof DEMO_DEVICES)[keyof typeof DEMO_DEVICES];
|
|
6
6
|
|
|
7
|
+
/** The viewer's unread notifications per device: the offline reception desktop's recordings failed overnight. */
|
|
8
|
+
const DEMO_UNREAD_NOTIFICATIONS: Partial<Record<DemoDevice['id'], number>> = {
|
|
9
|
+
'device-reception': 2,
|
|
10
|
+
'device-leo': 1,
|
|
11
|
+
};
|
|
12
|
+
|
|
7
13
|
function device(
|
|
8
14
|
cast: DemoCast,
|
|
9
15
|
demo: DemoDevice,
|
|
@@ -24,6 +30,7 @@ function device(
|
|
|
24
30
|
organizationId: organization.id,
|
|
25
31
|
organization: organization.name,
|
|
26
32
|
organizationImageUrl: organization.logoUrl,
|
|
33
|
+
unreadNotificationCount: DEMO_UNREAD_NOTIFICATIONS[demo.id],
|
|
27
34
|
};
|
|
28
35
|
}
|
|
29
36
|
|