andoncloud-workplaces-status-widget 1.2.13 → 1.2.15

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/index.d.ts CHANGED
@@ -19,10 +19,10 @@ declare const Widget: React.FC<WidgetProps<WidgetData, WidgetSettings>>;
19
19
  //#endregion
20
20
  //#region src/core/title.d.ts
21
21
  declare const getDisplayName: (lang: string) => string;
22
- declare const getTitle: (data: WidgetData | undefined, _settings: WidgetSettings | undefined, _filters: FilterValues | undefined, lang: string) => string;
22
+ declare const getTitle: (data: WidgetData | undefined, settings: WidgetSettings | undefined, _filters: FilterValues | undefined, lang: string) => string;
23
23
  //#endregion
24
24
  //#region src/version.d.ts
25
- declare const LIBRARY_VERSION = "1.2.13";
25
+ declare const LIBRARY_VERSION = "1.2.15";
26
26
  //#endregion
27
27
  //#region src/index.d.ts
28
28
  declare const thumbnail: string | undefined;
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { Checkbox, registerTranslations } from "andoncloud-sdk";
1
2
  import { useEffect, useMemo, useState } from "react";
2
3
  import { AndonLightColor, MetricCard, MetricTypeEnum, MetricUnitEnum, Period, SortableSelect, WorkplaceEvent, WorkplaceEventDocument, useGqlClients } from "andoncloud-dashboard-toolkit";
3
4
  import { BaseWidget } from "andoncloud-widget-base";
@@ -5,7 +6,6 @@ import { print } from "graphql";
5
6
  import { useTranslation } from "react-i18next";
6
7
  import { TabContext, TabList, TabPanel } from "@mui/lab";
7
8
  import { List, ListItem, ListItemButton, ListItemIcon, ListItemText, Tab, TextField } from "@mui/material";
8
- import { Checkbox } from "andoncloud-sdk";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import dayjs from "dayjs";
11
11
  import * as yup from "yup";
@@ -28,10 +28,10 @@ const resources = {
28
28
  "displayName": "Workplaces statuses",
29
29
  "titleWorkplaces_one": "{{count}} workplace",
30
30
  "titleWorkplaces_other": "{{count}} workplaces",
31
- "titleGreen_one": "{{count}} green",
32
- "titleGreen_other": "{{count}} green",
33
- "titleRed_one": "{{count}} red",
34
- "titleRed_other": "{{count}} red",
31
+ "titleGreen_one": "{{count}} working",
32
+ "titleGreen_other": "{{count}} working",
33
+ "titleRed_one": "{{count}} stopped",
34
+ "titleRed_other": "{{count}} stopped",
35
35
  "yellow": "Yellow"
36
36
  } } },
37
37
  pl: { translation: { workplacesStatusWidget: {
@@ -50,18 +50,18 @@ const resources = {
50
50
  "titleWorkplaces_one": "{{count}} stanowisko",
51
51
  "titleWorkplaces_few": "{{count}} stanowiska",
52
52
  "titleWorkplaces_many": "{{count}} stanowisk",
53
- "titleGreen_one": "{{count}} zielone",
54
- "titleGreen_few": "{{count}} zielone",
55
- "titleGreen_many": "{{count}} zielonych",
56
- "titleRed_one": "{{count}} czerwone",
57
- "titleRed_few": "{{count}} czerwone",
58
- "titleRed_many": "{{count}} czerwonych",
53
+ "titleGreen_one": "{{count}} pracuje",
54
+ "titleGreen_few": "{{count}} pracują",
55
+ "titleGreen_many": "{{count}} pracuje",
56
+ "titleRed_one": "{{count}} ma przestój",
57
+ "titleRed_few": "{{count}} mają przestój",
58
+ "titleRed_many": "{{count}} ma przestój",
59
59
  "yellow": "Żółty"
60
60
  } } }
61
61
  };
62
62
  //#endregion
63
63
  //#region src/version.ts
64
- const LIBRARY_VERSION = "1.2.13";
64
+ const LIBRARY_VERSION = "1.2.15";
65
65
  //#endregion
66
66
  //#region src/components/SettingsFormContent/index.tsx
67
67
  const SettingsFormContent = ({ data, formProps }) => {
@@ -336,14 +336,18 @@ const t = (key, lng, options) => i18n.t(`${ns}.${key}`, {
336
336
  ...options
337
337
  });
338
338
  const getDisplayName = (lang) => t("displayName", lang);
339
- const getTitle = (data, _settings, _filters, lang) => {
339
+ const getTitle = (data, settings, _filters, lang) => {
340
340
  const name = getDisplayName(lang);
341
- const workplaces = data?.workplaces;
341
+ const allWorkplaces = data?.workplaces;
342
342
  const statusChanges = data?.statusChanges;
343
- if (!workplaces?.length) return name;
343
+ if (!allWorkplaces?.length) return name;
344
+ const selectedIds = settings?.workplacesIds?.length ? new Set(settings.workplacesIds) : null;
345
+ const workplaces = selectedIds ? allWorkplaces.filter((wp) => selectedIds.has(wp.id)) : allWorkplaces;
346
+ if (!workplaces.length) return name;
344
347
  const latestByWorkplace = /* @__PURE__ */ new Map();
345
348
  for (const sc of statusChanges ?? []) {
346
349
  if (sc.finishedAt) continue;
350
+ if (selectedIds && !selectedIds.has(sc.workplaceId)) continue;
347
351
  latestByWorkplace.set(sc.workplaceId, sc.reason?.statusColor ?? "");
348
352
  }
349
353
  let green = 0;
@@ -357,6 +361,7 @@ const getTitle = (data, _settings, _filters, lang) => {
357
361
  };
358
362
  //#endregion
359
363
  //#region src/index.tsx
364
+ registerTranslations(resources);
360
365
  const thumbnail = void 0;
361
366
  const requiredFeatures = ["feature.workplaces-status-widget"];
362
367
  const extraPermissions = [];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["en","pl","locales"],"sources":["../src/locales/en/translation.json","../src/locales/pl/translation.json","../src/locales/index.ts","../src/version.ts","../src/components/SettingsFormContent/index.tsx","../src/components/StatusCard/helpers.ts","../src/components/StatusCard/index.tsx","../src/components/WidgetView/index.tsx","../src/components/Widget/utils.ts","../src/components/Widget/index.tsx","../src/core/title.ts","../src/index.tsx"],"sourcesContent":["","","import en from './en/translation.json';\nimport pl from './pl/translation.json';\n\nconst resources = {\n en: {\n translation: en,\n },\n pl: {\n translation: pl,\n },\n};\n\nexport default resources;\n","export const LIBRARY_VERSION = '1.2.13';\n","import { useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { TabContext, TabList, TabPanel } from '@mui/lab';\nimport { List, ListItem, ListItemButton, ListItemIcon, ListItemText, Tab, TextField } from '@mui/material';\nimport { SortableSelect } from 'andoncloud-dashboard-toolkit';\nimport { Checkbox } from 'andoncloud-sdk';\nimport { SettingsFormContentProps } from 'andoncloud-widget-base';\n\nimport { WidgetData, WidgetSettings } from '@/types';\n\nconst SettingsFormContent: React.FC<SettingsFormContentProps<WidgetData, WidgetSettings>> = ({ data, formProps }) => {\n // -- Local state --\n const [selectedTab, setSelectedTab] = useState('statuses');\n\n // -- Translation --\n const { t } = useTranslation();\n\n const statusOptions = useMemo(\n () => [\n { label: t('workplacesStatusWidget.green'), value: 'green' },\n { label: t('workplacesStatusWidget.yellow'), value: 'yellow' },\n { label: t('workplacesStatusWidget.red'), value: 'red' },\n { label: t('workplacesStatusWidget.gray'), value: 'gray' },\n ],\n [t],\n );\n\n const handleToggleWorkplaceSelected = (workplaceId: string) => {\n const selectedWorkplacesIds = formProps.values.workplacesIds || [];\n\n if (selectedWorkplacesIds.indexOf(workplaceId) !== -1) {\n formProps.setFieldValue(\n 'workplacesIds',\n selectedWorkplacesIds.filter((id) => id !== workplaceId),\n );\n } else {\n formProps.setFieldValue('workplacesIds', [...selectedWorkplacesIds, workplaceId]);\n }\n };\n\n return (\n <TabContext value={selectedTab}>\n <TabList onChange={(_, value) => setSelectedTab(value)} centered>\n <Tab label={t('workplacesStatusWidget.statuses')} value=\"statuses\" />\n <Tab label={t('workplacesStatusWidget.workplaces')} value=\"workplaces\" />\n <Tab label={t('workplacesStatusWidget.advanced')} value=\"advanced\" />\n </TabList>\n\n <TabPanel value=\"statuses\">\n <SortableSelect\n placeholder={`${t('workplacesStatusWidget.selectAndArrangeTheOrder')}...`}\n options={statusOptions}\n selected={formProps.values.statusColors || []}\n onChange={(selected) => formProps.setFieldValue('statusColors', [...selected])}\n />\n </TabPanel>\n\n <TabPanel value=\"workplaces\">\n <List sx={{ maxHeight: '500px', overflowY: 'scroll' }}>\n {data.workplaces?.map((workplace) => (\n <ListItem key={workplace.id}>\n <ListItemButton role={undefined} onClick={() => handleToggleWorkplaceSelected(workplace.id)} dense>\n <ListItemIcon>\n <Checkbox checked={(formProps.values.workplacesIds || []).indexOf(workplace.id) !== -1} />\n </ListItemIcon>\n <ListItemText id={workplace.id} primary={workplace.name} />\n </ListItemButton>\n </ListItem>\n ))}\n </List>\n </TabPanel>\n\n <TabPanel value=\"advanced\">\n <TextField\n name=\"customTitle\"\n label={t('workplacesStatusWidget.customTitle')}\n value={formProps.values.customTitle}\n onChange={formProps.handleChange}\n fullWidth\n />\n </TabPanel>\n </TabContext>\n );\n};\n\nexport default SettingsFormContent;\n","import { ListStatusChanges_StatusChange } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nexport const getDuration = (statusChange: ListStatusChanges_StatusChange) => {\n if (statusChange.finishedAt && statusChange.startedAt) {\n return Math.abs(dayjs(statusChange.startedAt).diff(dayjs(statusChange.finishedAt), 'seconds'));\n }\n return Math.abs(dayjs().diff(dayjs(statusChange.startedAt), 'seconds'));\n};\n","import { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { AndonLightColor, MetricCard, MetricTypeEnum, MetricUnitEnum, MetricValue } from 'andoncloud-dashboard-toolkit';\n\nimport { WorkplaceStatusProps } from '@/types';\n\nimport { getDuration } from './helpers';\n\nconst StatusCard: React.FC<WorkplaceStatusProps> = ({ companyConfig, workplace, statusChange }) => {\n const [metricValue, setMetricValue] = useState<MetricValue>({\n id: `last_status_change_${workplace.id}`,\n workplaceId: workplace.id,\n metricId: 'last_status_change',\n type: MetricTypeEnum.Kpi,\n statusColor: statusChange?.reason.statusColor || AndonLightColor.Gray,\n textValue: statusChange ? getDuration(statusChange).toString() : '0',\n unit: MetricUnitEnum.Duration,\n active: true,\n });\n const { t } = useTranslation();\n\n const workplaceConfig = companyConfig?.workplacesConfigs.find((config) => config.workplaceId === workplace.id);\n const orderLabel = !!workplaceConfig?.orderConfig.alternativeName ? t('workplacesStatusWidget.alternativeOrder') : t('workplacesStatusWidget.order');\n const orderNumber = statusChange?.order?.number;\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (statusChange) {\n setMetricValue((metric) => ({\n ...metric,\n statusColor: statusChange.reason.statusColor,\n textValue: getDuration(statusChange).toString(),\n }));\n\n if (!statusChange.finishedAt) {\n interval = setInterval(() => {\n setMetricValue((metric) => ({\n ...metric,\n statusColor: statusChange.reason.statusColor,\n textValue: getDuration(statusChange).toString(),\n }));\n }, 10_000);\n }\n }\n return () => {\n if (interval) clearInterval(interval);\n };\n }, [statusChange]);\n\n return (\n <MetricCard\n title={workplace.name}\n metricLabel={statusChange?.reason.name || ''}\n metricValue={metricValue}\n extraValue={`${orderLabel}: ${orderNumber || '-'}`}\n animateBackgroundColor={statusChange?.reason.temporary}\n rounded\n />\n );\n};\n\nexport default StatusCard;\n","import { useEffect, useState } from 'react';\n\nimport { List, ListItem } from '@mui/material';\nimport type { ListStatusChanges_StatusChange, ListWorkplaces_Workplace, Workplace } from 'andoncloud-dashboard-toolkit';\n\nimport { WidgetViewProps } from '@/types';\n\nimport StatusCard from '../StatusCard';\n\ninterface WorkplaceDetails {\n workplace: ListWorkplaces_Workplace;\n statusChange?: ListStatusChanges_StatusChange;\n}\n\nconst WidgetView: React.FC<WidgetViewProps> = ({ data, settings }) => {\n const [workplacesDetails, setWorkplacesDetails] = useState<WorkplaceDetails[]>([]);\n\n useEffect(() => {\n const workplacesIds = settings?.workplacesIds || [];\n const statusColors = settings?.statusColors || [];\n const getCurrentStatusChange = (workplace: Workplace) =>\n (data?.statusChanges || [])\n .filter((statusChange) => statusChange.workplaceId === workplace.id)\n .sort((a, b) => new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime())\n .pop();\n\n setWorkplacesDetails(\n (data.workplaces || [])\n .filter((workplace) => !workplacesIds.length || workplacesIds.indexOf(workplace.id) !== -1)\n .map((workplace) => ({ workplace, statusChange: getCurrentStatusChange(workplace) }))\n .filter(\n (details) =>\n !statusColors.length || statusColors.indexOf(details.statusChange?.reason.statusColor || '') !== -1,\n )\n .sort((a, b) => {\n const aStatusColor = a.statusChange?.reason.statusColor;\n const bStatusColor = b.statusChange?.reason.statusColor;\n\n if (aStatusColor && bStatusColor) {\n return statusColors.indexOf(aStatusColor) - statusColors.indexOf(bStatusColor);\n }\n return aStatusColor ? -1 : 1;\n }),\n );\n }, [data, settings]);\n\n return (\n <List sx={{ display: 'flex', height: '100%', '&:last-child': { marginRight: '10px' } }}>\n {workplacesDetails.slice(0, 6).map(({ workplace, statusChange }) => (\n <ListItem key={workplace.id} sx={{ minWidth: '15.5vw', marginLeft: '10px', padding: 0 }}>\n <StatusCard companyConfig={data.companyConfig} workplace={workplace} statusChange={statusChange} />\n </ListItem>\n ))}\n </List>\n );\n};\n\nexport default WidgetView;\n","import { TFunction } from 'i18next';\nimport * as yup from 'yup';\n\nexport const getSettingsFormProps = (t: TFunction) => {\n yup.setLocale({\n mixed: {\n required: t('workplacesStatusWidget.thisFieldIsRequired'),\n },\n });\n return {\n initialValues: {\n customTitle: '',\n statusColors: [],\n workplacesIds: [],\n },\n validationSchema: yup.object({\n statusColors: yup.array().of(yup.string()).required(),\n workplacesIds: yup.array().of(yup.string()).required(),\n }),\n };\n};\n","import { useEffect, useState } from 'react';\n\nimport {\n Period,\n StatusChange,\n useGqlClients,\n WidgetProps,\n WorkplaceEvent,\n WorkplaceEventDocument,\n WorkplaceEventSubscriptionPayload,\n} from 'andoncloud-dashboard-toolkit';\nimport { BaseWidget } from 'andoncloud-widget-base';\nimport { print } from 'graphql';\n\nimport locales from '@/locales';\nimport { WidgetData, WidgetSettings } from '@/types';\nimport { LIBRARY_VERSION } from '@/version';\n\nimport SettingsFormContent from '../SettingsFormContent';\nimport WidgetView from '../WidgetView';\n\nimport { getSettingsFormProps } from './utils';\n\nconst Widget: React.FC<WidgetProps<WidgetData, WidgetSettings>> = ({ url, wsUrl, lang, data, ...widgetProps }) => {\n const { graphqlSdk, gqlWsClient } = useGqlClients({ url, wsUrl, lang });\n const [gqlWsSubscribed, setGqlWsSubscribed] = useState<boolean>(false);\n const [widgetData, setWidgetData] = useState<WidgetData | undefined>(data);\n\n useEffect(() => {\n if (!widgetData && graphqlSdk) {\n graphqlSdk\n .companyConfig()\n .then(({ companyConfig }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n companyConfig,\n })),\n )\n .catch(() => {});\n\n graphqlSdk\n .listWorkplaces()\n .then(({ workplaces }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n workplaces,\n })),\n )\n .catch(() => {});\n\n graphqlSdk\n .listStatusChanges({ filter: { period: Period.CurrentShift } })\n .then(({ statusChanges }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges,\n })),\n )\n .catch(() => {});\n }\n if (widgetData?.workplaces && gqlWsClient && !gqlWsSubscribed) {\n widgetData.workplaces.forEach(({ id }) => {\n gqlWsClient.subscribe<WorkplaceEventSubscriptionPayload>(\n print(WorkplaceEventDocument),\n { id },\n ({ event, subject }) => {\n if (event === WorkplaceEvent.StatusChangeCreated) {\n const statusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges: [statusChange, ...current.statusChanges],\n }));\n } else if (event === WorkplaceEvent.StatusChangeUpdated) {\n const updatedStatusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => {\n const statusChanges = current.statusChanges.map((statusChange) =>\n statusChange.id === updatedStatusChange.id ? updatedStatusChange : statusChange,\n );\n return {\n ...(current || {}),\n statusChanges,\n };\n });\n } else if (event === WorkplaceEvent.CurrentShiftChanged && graphqlSdk) {\n graphqlSdk\n .listStatusChanges({ filter: { period: Period.CurrentShift } })\n .then(({ statusChanges }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges,\n })),\n )\n .catch(() => {});\n }\n },\n );\n setGqlWsSubscribed(true);\n });\n }\n }, [data, graphqlSdk, gqlWsClient, gqlWsSubscribed, widgetData]);\n\n return (\n <BaseWidget\n {...widgetProps}\n lang={lang}\n locales={locales}\n data={widgetData}\n gqlClients={{ graphqlSdk, gqlWsClient }}\n WidgetView={WidgetView}\n getSettingsFormProps={getSettingsFormProps}\n SettingsFormContent={SettingsFormContent}\n version={LIBRARY_VERSION}\n data-testid=\"workplaces-status-widget\"\n />\n );\n};\n\nexport default Widget;\n","import type { FilterValues } from 'andoncloud-dashboard-toolkit';\nimport i18n from 'i18next';\n\nimport type { WidgetData, WidgetSettings } from '../types';\n\nconst ns = 'workplacesStatusWidget';\n\nconst t = (key: string, lng: string, options?: Record<string, unknown>) => i18n.t(`${ns}.${key}`, { lng, ...options });\n\nexport const getDisplayName = (lang: string) => t('displayName', lang);\n\nexport const getTitle = (\n data: WidgetData | undefined,\n _settings: WidgetSettings | undefined,\n _filters: FilterValues | undefined,\n lang: string,\n): string => {\n const name = getDisplayName(lang);\n\n const workplaces = data?.workplaces;\n const statusChanges = data?.statusChanges;\n if (!workplaces?.length) return name;\n\n const latestByWorkplace = new Map<string, string>();\n for (const sc of statusChanges ?? []) {\n if (sc.finishedAt) continue;\n latestByWorkplace.set(sc.workplaceId, sc.reason?.statusColor ?? '');\n }\n\n let green = 0;\n let red = 0;\n for (const color of latestByWorkplace.values()) {\n if (color === 'green') green++;\n else if (color === 'red') red++;\n }\n\n const parts = [t('titleWorkplaces', lang, { count: workplaces.length })];\n if (green > 0) parts.push(t('titleGreen', lang, { count: green }));\n if (red > 0) parts.push(t('titleRed', lang, { count: red }));\n\n return `${name} — ${parts.join(', ')}`;\n};\n","export { default as Widget } from './components/Widget';\nexport { getDisplayName, getTitle } from './core/title';\n\nexport const thumbnail: string | undefined = undefined;\n\nexport const requiredFeatures: string[] = ['feature.workplaces-status-widget'];\nexport const extraPermissions: string[] = [];\n\nexport { LIBRARY_VERSION as version } from './version';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["en","pl","locales","locales"],"sources":["../src/locales/en/translation.json","../src/locales/pl/translation.json","../src/locales/index.ts","../src/version.ts","../src/components/SettingsFormContent/index.tsx","../src/components/StatusCard/helpers.ts","../src/components/StatusCard/index.tsx","../src/components/WidgetView/index.tsx","../src/components/Widget/utils.ts","../src/components/Widget/index.tsx","../src/core/title.ts","../src/index.tsx"],"sourcesContent":["","","import en from './en/translation.json';\nimport pl from './pl/translation.json';\n\nconst resources = {\n en: {\n translation: en,\n },\n pl: {\n translation: pl,\n },\n};\n\nexport default resources;\n","export const LIBRARY_VERSION = '1.2.15';\n","import { useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { TabContext, TabList, TabPanel } from '@mui/lab';\nimport { List, ListItem, ListItemButton, ListItemIcon, ListItemText, Tab, TextField } from '@mui/material';\nimport { SortableSelect } from 'andoncloud-dashboard-toolkit';\nimport { Checkbox } from 'andoncloud-sdk';\nimport { SettingsFormContentProps } from 'andoncloud-widget-base';\n\nimport { WidgetData, WidgetSettings } from '@/types';\n\nconst SettingsFormContent: React.FC<SettingsFormContentProps<WidgetData, WidgetSettings>> = ({ data, formProps }) => {\n // -- Local state --\n const [selectedTab, setSelectedTab] = useState('statuses');\n\n // -- Translation --\n const { t } = useTranslation();\n\n const statusOptions = useMemo(\n () => [\n { label: t('workplacesStatusWidget.green'), value: 'green' },\n { label: t('workplacesStatusWidget.yellow'), value: 'yellow' },\n { label: t('workplacesStatusWidget.red'), value: 'red' },\n { label: t('workplacesStatusWidget.gray'), value: 'gray' },\n ],\n [t],\n );\n\n const handleToggleWorkplaceSelected = (workplaceId: string) => {\n const selectedWorkplacesIds = formProps.values.workplacesIds || [];\n\n if (selectedWorkplacesIds.indexOf(workplaceId) !== -1) {\n formProps.setFieldValue(\n 'workplacesIds',\n selectedWorkplacesIds.filter((id) => id !== workplaceId),\n );\n } else {\n formProps.setFieldValue('workplacesIds', [...selectedWorkplacesIds, workplaceId]);\n }\n };\n\n return (\n <TabContext value={selectedTab}>\n <TabList onChange={(_, value) => setSelectedTab(value)} centered>\n <Tab label={t('workplacesStatusWidget.statuses')} value=\"statuses\" />\n <Tab label={t('workplacesStatusWidget.workplaces')} value=\"workplaces\" />\n <Tab label={t('workplacesStatusWidget.advanced')} value=\"advanced\" />\n </TabList>\n\n <TabPanel value=\"statuses\">\n <SortableSelect\n placeholder={`${t('workplacesStatusWidget.selectAndArrangeTheOrder')}...`}\n options={statusOptions}\n selected={formProps.values.statusColors || []}\n onChange={(selected) => formProps.setFieldValue('statusColors', [...selected])}\n />\n </TabPanel>\n\n <TabPanel value=\"workplaces\">\n <List sx={{ maxHeight: '500px', overflowY: 'scroll' }}>\n {data.workplaces?.map((workplace) => (\n <ListItem key={workplace.id}>\n <ListItemButton role={undefined} onClick={() => handleToggleWorkplaceSelected(workplace.id)} dense>\n <ListItemIcon>\n <Checkbox checked={(formProps.values.workplacesIds || []).indexOf(workplace.id) !== -1} />\n </ListItemIcon>\n <ListItemText id={workplace.id} primary={workplace.name} />\n </ListItemButton>\n </ListItem>\n ))}\n </List>\n </TabPanel>\n\n <TabPanel value=\"advanced\">\n <TextField\n name=\"customTitle\"\n label={t('workplacesStatusWidget.customTitle')}\n value={formProps.values.customTitle}\n onChange={formProps.handleChange}\n fullWidth\n />\n </TabPanel>\n </TabContext>\n );\n};\n\nexport default SettingsFormContent;\n","import { ListStatusChanges_StatusChange } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nexport const getDuration = (statusChange: ListStatusChanges_StatusChange) => {\n if (statusChange.finishedAt && statusChange.startedAt) {\n return Math.abs(dayjs(statusChange.startedAt).diff(dayjs(statusChange.finishedAt), 'seconds'));\n }\n return Math.abs(dayjs().diff(dayjs(statusChange.startedAt), 'seconds'));\n};\n","import { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { AndonLightColor, MetricCard, MetricTypeEnum, MetricUnitEnum, MetricValue } from 'andoncloud-dashboard-toolkit';\n\nimport { WorkplaceStatusProps } from '@/types';\n\nimport { getDuration } from './helpers';\n\nconst StatusCard: React.FC<WorkplaceStatusProps> = ({ companyConfig, workplace, statusChange }) => {\n const [metricValue, setMetricValue] = useState<MetricValue>({\n id: `last_status_change_${workplace.id}`,\n workplaceId: workplace.id,\n metricId: 'last_status_change',\n type: MetricTypeEnum.Kpi,\n statusColor: statusChange?.reason.statusColor || AndonLightColor.Gray,\n textValue: statusChange ? getDuration(statusChange).toString() : '0',\n unit: MetricUnitEnum.Duration,\n active: true,\n });\n const { t } = useTranslation();\n\n const workplaceConfig = companyConfig?.workplacesConfigs.find((config) => config.workplaceId === workplace.id);\n const orderLabel = !!workplaceConfig?.orderConfig.alternativeName ? t('workplacesStatusWidget.alternativeOrder') : t('workplacesStatusWidget.order');\n const orderNumber = statusChange?.order?.number;\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (statusChange) {\n setMetricValue((metric) => ({\n ...metric,\n statusColor: statusChange.reason.statusColor,\n textValue: getDuration(statusChange).toString(),\n }));\n\n if (!statusChange.finishedAt) {\n interval = setInterval(() => {\n setMetricValue((metric) => ({\n ...metric,\n statusColor: statusChange.reason.statusColor,\n textValue: getDuration(statusChange).toString(),\n }));\n }, 10_000);\n }\n }\n return () => {\n if (interval) clearInterval(interval);\n };\n }, [statusChange]);\n\n return (\n <MetricCard\n title={workplace.name}\n metricLabel={statusChange?.reason.name || ''}\n metricValue={metricValue}\n extraValue={`${orderLabel}: ${orderNumber || '-'}`}\n animateBackgroundColor={statusChange?.reason.temporary}\n rounded\n />\n );\n};\n\nexport default StatusCard;\n","import { useEffect, useState } from 'react';\n\nimport { List, ListItem } from '@mui/material';\nimport type { ListStatusChanges_StatusChange, ListWorkplaces_Workplace, Workplace } from 'andoncloud-dashboard-toolkit';\n\nimport { WidgetViewProps } from '@/types';\n\nimport StatusCard from '../StatusCard';\n\ninterface WorkplaceDetails {\n workplace: ListWorkplaces_Workplace;\n statusChange?: ListStatusChanges_StatusChange;\n}\n\nconst WidgetView: React.FC<WidgetViewProps> = ({ data, settings }) => {\n const [workplacesDetails, setWorkplacesDetails] = useState<WorkplaceDetails[]>([]);\n\n useEffect(() => {\n const workplacesIds = settings?.workplacesIds || [];\n const statusColors = settings?.statusColors || [];\n const getCurrentStatusChange = (workplace: Workplace) =>\n (data?.statusChanges || [])\n .filter((statusChange) => statusChange.workplaceId === workplace.id)\n .sort((a, b) => new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime())\n .pop();\n\n setWorkplacesDetails(\n (data.workplaces || [])\n .filter((workplace) => !workplacesIds.length || workplacesIds.indexOf(workplace.id) !== -1)\n .map((workplace) => ({ workplace, statusChange: getCurrentStatusChange(workplace) }))\n .filter(\n (details) =>\n !statusColors.length || statusColors.indexOf(details.statusChange?.reason.statusColor || '') !== -1,\n )\n .sort((a, b) => {\n const aStatusColor = a.statusChange?.reason.statusColor;\n const bStatusColor = b.statusChange?.reason.statusColor;\n\n if (aStatusColor && bStatusColor) {\n return statusColors.indexOf(aStatusColor) - statusColors.indexOf(bStatusColor);\n }\n return aStatusColor ? -1 : 1;\n }),\n );\n }, [data, settings]);\n\n return (\n <List sx={{ display: 'flex', height: '100%', '&:last-child': { marginRight: '10px' } }}>\n {workplacesDetails.slice(0, 6).map(({ workplace, statusChange }) => (\n <ListItem key={workplace.id} sx={{ minWidth: '15.5vw', marginLeft: '10px', padding: 0 }}>\n <StatusCard companyConfig={data.companyConfig} workplace={workplace} statusChange={statusChange} />\n </ListItem>\n ))}\n </List>\n );\n};\n\nexport default WidgetView;\n","import { TFunction } from 'i18next';\nimport * as yup from 'yup';\n\nexport const getSettingsFormProps = (t: TFunction) => {\n yup.setLocale({\n mixed: {\n required: t('workplacesStatusWidget.thisFieldIsRequired'),\n },\n });\n return {\n initialValues: {\n customTitle: '',\n statusColors: [],\n workplacesIds: [],\n },\n validationSchema: yup.object({\n statusColors: yup.array().of(yup.string()).required(),\n workplacesIds: yup.array().of(yup.string()).required(),\n }),\n };\n};\n","import { useEffect, useState } from 'react';\n\nimport {\n Period,\n StatusChange,\n useGqlClients,\n WidgetProps,\n WorkplaceEvent,\n WorkplaceEventDocument,\n WorkplaceEventSubscriptionPayload,\n} from 'andoncloud-dashboard-toolkit';\nimport { BaseWidget } from 'andoncloud-widget-base';\nimport { print } from 'graphql';\n\nimport locales from '@/locales';\nimport { WidgetData, WidgetSettings } from '@/types';\nimport { LIBRARY_VERSION } from '@/version';\n\nimport SettingsFormContent from '../SettingsFormContent';\nimport WidgetView from '../WidgetView';\n\nimport { getSettingsFormProps } from './utils';\n\nconst Widget: React.FC<WidgetProps<WidgetData, WidgetSettings>> = ({ url, wsUrl, lang, data, ...widgetProps }) => {\n const { graphqlSdk, gqlWsClient } = useGqlClients({ url, wsUrl, lang });\n const [gqlWsSubscribed, setGqlWsSubscribed] = useState<boolean>(false);\n const [widgetData, setWidgetData] = useState<WidgetData | undefined>(data);\n\n useEffect(() => {\n if (!widgetData && graphqlSdk) {\n graphqlSdk\n .companyConfig()\n .then(({ companyConfig }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n companyConfig,\n })),\n )\n .catch(() => {});\n\n graphqlSdk\n .listWorkplaces()\n .then(({ workplaces }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n workplaces,\n })),\n )\n .catch(() => {});\n\n graphqlSdk\n .listStatusChanges({ filter: { period: Period.CurrentShift } })\n .then(({ statusChanges }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges,\n })),\n )\n .catch(() => {});\n }\n if (widgetData?.workplaces && gqlWsClient && !gqlWsSubscribed) {\n widgetData.workplaces.forEach(({ id }) => {\n gqlWsClient.subscribe<WorkplaceEventSubscriptionPayload>(\n print(WorkplaceEventDocument),\n { id },\n ({ event, subject }) => {\n if (event === WorkplaceEvent.StatusChangeCreated) {\n const statusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges: [statusChange, ...current.statusChanges],\n }));\n } else if (event === WorkplaceEvent.StatusChangeUpdated) {\n const updatedStatusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => {\n const statusChanges = current.statusChanges.map((statusChange) =>\n statusChange.id === updatedStatusChange.id ? updatedStatusChange : statusChange,\n );\n return {\n ...(current || {}),\n statusChanges,\n };\n });\n } else if (event === WorkplaceEvent.CurrentShiftChanged && graphqlSdk) {\n graphqlSdk\n .listStatusChanges({ filter: { period: Period.CurrentShift } })\n .then(({ statusChanges }) =>\n setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges,\n })),\n )\n .catch(() => {});\n }\n },\n );\n setGqlWsSubscribed(true);\n });\n }\n }, [data, graphqlSdk, gqlWsClient, gqlWsSubscribed, widgetData]);\n\n return (\n <BaseWidget\n {...widgetProps}\n lang={lang}\n locales={locales}\n data={widgetData}\n gqlClients={{ graphqlSdk, gqlWsClient }}\n WidgetView={WidgetView}\n getSettingsFormProps={getSettingsFormProps}\n SettingsFormContent={SettingsFormContent}\n version={LIBRARY_VERSION}\n data-testid=\"workplaces-status-widget\"\n />\n );\n};\n\nexport default Widget;\n","import type { FilterValues } from 'andoncloud-dashboard-toolkit';\nimport i18n from 'i18next';\n\nimport type { WidgetData, WidgetSettings } from '../types';\n\nconst ns = 'workplacesStatusWidget';\n\nconst t = (key: string, lng: string, options?: Record<string, unknown>) => i18n.t(`${ns}.${key}`, { lng, ...options });\n\nexport const getDisplayName = (lang: string) => t('displayName', lang);\n\nexport const getTitle = (\n data: WidgetData | undefined,\n settings: WidgetSettings | undefined,\n _filters: FilterValues | undefined,\n lang: string,\n): string => {\n const name = getDisplayName(lang);\n\n const allWorkplaces = data?.workplaces;\n const statusChanges = data?.statusChanges;\n if (!allWorkplaces?.length) return name;\n\n const selectedIds = settings?.workplacesIds?.length ? new Set(settings.workplacesIds) : null;\n const workplaces = selectedIds ? allWorkplaces.filter((wp) => selectedIds.has(wp.id)) : allWorkplaces;\n if (!workplaces.length) return name;\n\n const latestByWorkplace = new Map<string, string>();\n for (const sc of statusChanges ?? []) {\n if (sc.finishedAt) continue;\n if (selectedIds && !selectedIds.has(sc.workplaceId)) continue;\n latestByWorkplace.set(sc.workplaceId, sc.reason?.statusColor ?? '');\n }\n\n let green = 0;\n let red = 0;\n for (const color of latestByWorkplace.values()) {\n if (color === 'green') green++;\n else if (color === 'red') red++;\n }\n\n const parts = [t('titleWorkplaces', lang, { count: workplaces.length })];\n if (green > 0) parts.push(t('titleGreen', lang, { count: green }));\n if (red > 0) parts.push(t('titleRed', lang, { count: red }));\n\n return `${name} — ${parts.join(', ')}`;\n};\n","import { registerTranslations } from 'andoncloud-sdk';\n\nimport locales from './locales';\n\nregisterTranslations(locales);\n\nexport { default as Widget } from './components/Widget';\nexport { getDisplayName, getTitle } from './core/title';\n\nexport const thumbnail: string | undefined = undefined;\n\nexport const requiredFeatures: string[] = ['feature.workplaces-status-widget'];\nexport const extraPermissions: string[] = [];\n\nexport { LIBRARY_VERSION as version } from './version';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "andoncloud-workplaces-status-widget",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
4
4
  "description": "Made with create-andoncloud-widget",
5
5
  "author": "Adrian Olszewski",
6
6
  "license": "MIT",
@@ -28,6 +28,7 @@
28
28
  "andoncloud-dashboard-toolkit": "^1.0.0",
29
29
  "andoncloud-sdk": "^1.0.0",
30
30
  "andoncloud-widget-base": "^1.0.0",
31
+ "dayjs": "^1.11.0",
31
32
  "graphql-request": "^6.0.0",
32
33
  "i18next": "^22.0.0",
33
34
  "react": "^18.0.0",
@@ -43,10 +44,10 @@
43
44
  "@mui/x-date-pickers": "^8.27.2",
44
45
  "@types/react": "^19.2.14",
45
46
  "ajv": "^8.18.0",
46
- "andoncloud-dashboard-toolkit": "^1.5.59",
47
+ "andoncloud-dashboard-toolkit": "^1.5.63",
47
48
  "andoncloud-library-scripts": "^2.0.0",
48
49
  "andoncloud-sdk": "^1.7.25",
49
- "andoncloud-widget-base": "^1.2.24",
50
+ "andoncloud-widget-base": "^1.2.25",
50
51
  "cypress": "^15.13.0",
51
52
  "eslint-config-andoncloud": "^1.1.0",
52
53
  "graphql-request": "^6.1.0",
@@ -71,7 +72,6 @@
71
72
  "dependencies": {
72
73
  "actioncable": "^5.2.8",
73
74
  "array-move": "^4.0.0",
74
- "dayjs": "^1.11.20",
75
75
  "react-select": "^5.10.2",
76
76
  "react-sortable-hoc": "^2.0.0",
77
77
  "yup": "^1.7.1"