andoncloud-workplaces-state-timelines-widget 1.2.8 → 1.2.9

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
@@ -21,7 +21,7 @@ declare const getDisplayName: (lang: string) => string;
21
21
  declare const getTitle: (data: WidgetData | undefined, settings: WidgetSettings | undefined, _filters: FilterValues | undefined, lang: string) => string;
22
22
  //#endregion
23
23
  //#region src/version.d.ts
24
- declare const LIBRARY_VERSION = "1.2.8";
24
+ declare const LIBRARY_VERSION = "1.2.9";
25
25
  //#endregion
26
26
  //#region src/index.d.ts
27
27
  declare const thumbnail: string | undefined;
package/dist/index.js CHANGED
@@ -26,7 +26,8 @@ const resources = {
26
26
  "selectAndArrangeTheOrder": "Select and arrange the order",
27
27
  "settings": "Settings",
28
28
  "thisFieldIsRequired": "This field is required",
29
- "displayName": "Status changes history for current shift",
29
+ "displayName": "Status changes history",
30
+ "titleCurrentShift": "current shift",
30
31
  "titleWorkplaces_one": "{{count}} workplace",
31
32
  "titleWorkplaces_other": "{{count}} workplaces",
32
33
  "workplaces": "Workplaces"
@@ -41,7 +42,8 @@ const resources = {
41
42
  "selectAndArrangeTheOrder": "Wybierz i ustal kolejność",
42
43
  "settings": "Ustawienia",
43
44
  "thisFieldIsRequired": "To pole jest wymagane",
44
- "displayName": "Historia zmian statusów dla obecnej zmiany",
45
+ "displayName": "Historia zmian statusów",
46
+ "titleCurrentShift": "aktualna zmiana",
45
47
  "titleWorkplaces_one": "{{count}} stanowisko",
46
48
  "titleWorkplaces_few": "{{count}} stanowiska",
47
49
  "titleWorkplaces_many": "{{count}} stanowisk",
@@ -50,7 +52,7 @@ const resources = {
50
52
  };
51
53
  //#endregion
52
54
  //#region src/version.ts
53
- const LIBRARY_VERSION = "1.2.8";
55
+ const LIBRARY_VERSION = "1.2.9";
54
56
  //#endregion
55
57
  //#region src/components/SettingsFormContent/index.tsx
56
58
  const SettingsFormContent = ({ data, formProps }) => {
@@ -362,7 +364,7 @@ const getTitle = (data, settings, _filters, lang) => {
362
364
  const selectedIds = settings?.workplacesIds?.length ? new Set(settings.workplacesIds) : null;
363
365
  const workplaces = selectedIds ? allWorkplaces.filter((wp) => selectedIds.has(wp.id)) : allWorkplaces;
364
366
  if (!workplaces.length) return name;
365
- return `${name} — ${t("titleWorkplaces", lang, { count: workplaces.length })}`;
367
+ return `${name} — ${t("titleCurrentShift", lang)}, ${t("titleWorkplaces", lang, { count: workplaces.length })}`;
366
368
  };
367
369
  //#endregion
368
370
  //#region src/index.tsx
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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/helpers.ts","../src/components/TimelineLoader/index.tsx","../src/components/Timeline/styled.ts","../src/components/Timeline/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.8';\n","import { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { TabContext, TabList, TabPanel } from '@mui/lab';\nimport { Tab, TextField } from '@mui/material';\nimport { SortableSelect } from 'andoncloud-dashboard-toolkit';\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('workplaces');\n\n // -- Translation --\n const { t } = useTranslation();\n\n return (\n <TabContext value={selectedTab}>\n <TabList onChange={(_, value) => setSelectedTab(value)} centered>\n <Tab label={t('workplacesStateTimelinesWidget.workplaces')} value=\"workplaces\" />\n <Tab label={t('workplacesStateTimelinesWidget.advanced')} value=\"advanced\" />\n </TabList>\n\n <TabPanel value=\"workplaces\">\n <SortableSelect\n placeholder={`${t('workplacesStateTimelinesWidget.selectAndArrangeTheOrder')}...`}\n options={data.workplaces?.map(({ id, name }) => ({ label: name, value: id }))}\n selected={formProps.values.workplacesIds}\n onChange={(selected) => formProps.setFieldValue('workplacesIds', [...selected])}\n />\n </TabPanel>\n\n <TabPanel value=\"advanced\">\n <TextField\n name=\"customTitle\"\n label={t('workplacesStateTimelinesWidget.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 { AndonLightColor, ListStatusChanges_StatusChange, NormalizedShift } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nexport const durationSeconds = (\n shift: NormalizedShift,\n statusChange: ListStatusChanges_StatusChange,\n currentDate: Date,\n) => {\n const startedAt = shift.startedAt.isAfter(statusChange.startedAt) ? shift.startedAt : dayjs(statusChange.startedAt);\n\n if (startedAt && statusChange.finishedAt) {\n return Math.abs(startedAt.diff(dayjs(statusChange.finishedAt), 'seconds'));\n }\n return Math.abs(dayjs(currentDate).diff(startedAt, 'seconds'));\n};\n\nexport const mapTimelineColor = (color: AndonLightColor): string => {\n switch (color) {\n case 'green':\n return '#2ACB42';\n case 'red':\n return '#FF453A';\n case 'yellow':\n return '#FFC12F';\n default:\n return '#525860';\n }\n};\n","import ContentLoader from 'react-content-loader';\n\nconst TimelineLoader = () => (\n <ContentLoader\n data-testid=\"timeline-loading\"\n height=\"28\"\n width=\"100%\"\n speed={1.5}\n backgroundColor=\"#3d3d3d\"\n foregroundColor=\"#ffffff\"\n >\n <rect x=\"4%\" y=\"10\" ry=\"6\" width=\"92%\" height=\"14\" />\n </ContentLoader>\n);\n\nexport default TimelineLoader;\n","import { styled } from '@mui/material/styles';\nimport { AndonLightColor } from 'andoncloud-dashboard-toolkit';\n\nimport { mapTimelineColor } from '@/helpers';\n\nexport interface TimelineElementProps {\n percentWidth: number;\n color?: AndonLightColor;\n}\n\nexport const TimelineRow = styled('div')({\n display: 'flex',\n flexGrow: 1,\n alignItems: 'center',\n padding: '10px 0',\n background: '#252A32',\n '&:nth-of-type(2n)': {\n background: '#30353d',\n },\n});\n\nexport const TimelineWrapper = styled('div')({\n display: 'flex',\n margin: '6px 0',\n zIndex: 3,\n flexDirection: 'row',\n height: '20px',\n width: '100%',\n overflow: 'hidden',\n borderRadius: '4px',\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\n});\n\nexport const TimelineTimeInfoContainer = styled('div')({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n});\n\nexport const TimelineTimeInfo = styled('span')({\n margin: '0 1.5em',\n fontSize: '12px',\n fontWeight: 500,\n lineHeight: '12px',\n color: 'rgba(255, 255, 255, 0.5)',\n});\n\nexport const TimelineElement = styled('div')<TimelineElementProps>(({ percentWidth, color }) => ({\n flexBasis: `${percentWidth}%`,\n flexShrink: 0,\n backgroundColor: mapTimelineColor(color as AndonLightColor),\n '&:first-of-type': {\n borderTopLeftRadius: '4px',\n borderBottomLeftRadius: '4px',\n },\n}));\n","import { Fragment, useCallback, useEffect, useState } from 'react';\n\nimport { Typography } from '@mui/material';\nimport { ListStatusChanges_StatusChange, NormalizedShift } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\nimport isBetween from 'dayjs/plugin/isBetween';\n\nimport { durationSeconds } from '@/helpers';\n\ndayjs.extend(isBetween);\n\nimport TimelineLoader from '../TimelineLoader';\n\nimport { TimelineElement, TimelineRow, TimelineTimeInfo, TimelineWrapper } from './styled';\n\nexport interface TimelineProps {\n title: string;\n shift: NormalizedShift | null;\n statusChanges: ListStatusChanges_StatusChange[];\n loading?: boolean;\n}\n\nconst Timeline: React.FC<TimelineProps> = ({ title, shift, statusChanges, loading }) => {\n const [shiftStatusChanges, setShiftStatusChanges] = useState<ListStatusChanges_StatusChange[]>([]);\n const calculateShiftDuration = useCallback(() => {\n return shift ? Math.abs(shift.startedAt.diff(shift.finishedAt, 'seconds')) : 0;\n }, [shift]);\n const isShiftStatusChange = useCallback(\n (statusChange: ListStatusChanges_StatusChange) => {\n const startedAt = dayjs(statusChange.startedAt);\n const finishedAt = statusChange.finishedAt ? dayjs(statusChange.finishedAt) : null;\n\n if (shift) {\n return (\n startedAt.isBetween(shift.startedAt, shift.finishedAt) ||\n finishedAt?.isBetween(shift.startedAt, shift.finishedAt) ||\n (startedAt.isBefore(shift.startedAt) && !finishedAt)\n );\n }\n return false;\n },\n [shift],\n );\n const [shiftDuration, setShiftDuration] = useState<number>(() => calculateShiftDuration());\n\n useEffect(() => {\n setShiftDuration(calculateShiftDuration());\n }, [shift, calculateShiftDuration]);\n\n useEffect(() => {\n setShiftStatusChanges(statusChanges.filter((statusChange) => isShiftStatusChange(statusChange)));\n }, [statusChanges, isShiftStatusChange]);\n\n if (loading) return <TimelineLoader />;\n\n return (\n <TimelineRow>\n <Typography\n sx={{\n display: title ? 'block' : 'none',\n flexBasis: '25%',\n marginLeft: '20px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n color: 'white',\n }}\n >\n {title}\n </Typography>\n {shift && (\n <Fragment>\n <TimelineTimeInfo>{shift.startedAt.format('HH:mm')}</TimelineTimeInfo>\n <TimelineWrapper data-testid=\"timeline\">\n {shiftStatusChanges?.map(\n (status) =>\n status.reason.statusColor && (\n <TimelineElement\n data-testid={`timeline-element-${status.id}-color-${status.reason.statusColor}`}\n key={`${status.id}${status.author.id}`}\n color={status.reason.statusColor}\n percentWidth={Math.min((durationSeconds(shift, status, new Date()) / shiftDuration) * 100, 100)}\n />\n ),\n )}\n </TimelineWrapper>\n <TimelineTimeInfo>{shift.finishedAt.format('HH:mm')}</TimelineTimeInfo>\n </Fragment>\n )}\n </TimelineRow>\n );\n};\n\nexport default Timeline;\n","import { useEffect, useState } from 'react';\n\nimport { Box } from '@mui/material';\nimport { getCurrentShift, NormalizedShift, normalizeShifts } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nimport { WidgetViewProps } from '@/types';\n\nimport Timeline from '../Timeline';\n\nconst WidgetView: React.FC<WidgetViewProps> = ({ data, settings }) => {\n const [currentShift, setCurrentShift] = useState<NormalizedShift | null>(null);\n const getTitle = (workplaceId: string) => {\n const workplaces = data.workplaces;\n\n return settings?.workplacesIds?.length === 1\n ? ''\n : workplaces?.find((workplace) => workplace.id === workplaceId)?.name || '';\n };\n\n useEffect(() => {\n const updateCurrentShift = () => {\n const currentDate = dayjs();\n\n setCurrentShift(getCurrentShift(currentDate, normalizeShifts(data?.shifts || [], currentDate)));\n };\n const intervalId = setInterval(() => updateCurrentShift(), 10 * 1000);\n\n updateCurrentShift();\n\n return () => {\n clearInterval(intervalId);\n };\n }, [data?.shifts]);\n\n return (\n <Box display=\"flex\" flexDirection=\"column\" height=\"100%\">\n {settings?.workplacesIds.map((workplaceId) => (\n <Timeline\n key={workplaceId}\n title={getTitle(workplaceId)}\n shift={currentShift}\n statusChanges={data.statusChanges?.filter((statusChange) => statusChange.workplaceId === workplaceId) || []}\n loading={data === undefined}\n />\n ))}\n </Box>\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('workplacesStateTimelinesWidget.thisFieldIsRequired'),\n },\n });\n return {\n initialValues: {\n customTitle: '',\n workplacesIds: [],\n },\n validationSchema: yup.object({\n workplacesIds: yup.array().of(yup.string()).required(),\n }),\n };\n};\n","import { useCallback, useEffect, useState } from 'react';\n\nimport {\n ListStatusChanges_StatusChange,\n StatusChange,\n useGqlClients,\n WidgetProps,\n WorkplaceEvent,\n WorkplaceEventDocument,\n WorkplaceEventSubscriptionPayload,\n} from 'andoncloud-dashboard-toolkit';\nimport { BaseWidget } from 'andoncloud-widget-base';\nimport dayjs from 'dayjs';\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>> = ({\n url,\n wsUrl,\n lang,\n data,\n settings,\n ...widgetProps\n}) => {\n const { graphqlSdk, gqlWsClient } = useGqlClients({ url, wsUrl, lang });\n const [widgetData, setWidgetData] = useState<WidgetData | undefined>(data);\n const [widgetSettings, setWidgetSettings] = useState<WidgetSettings | undefined>(settings);\n\n const sortStatusChagnges = (items: ListStatusChanges_StatusChange[]): ListStatusChanges_StatusChange[] => {\n return items.sort((item1, item2) => {\n if (item1.finishedAt && item2.finishedAt) return dayjs(item1.finishedAt).diff(dayjs(item2.finishedAt));\n return item1.finishedAt ? -1 : 1;\n });\n };\n\n useEffect(() => {\n if (!data && graphqlSdk) {\n graphqlSdk\n .listShifts()\n .then(({ shifts }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n shifts,\n }));\n })\n .catch(() => {});\n\n graphqlSdk\n .listWorkplaces()\n .then(({ workplaces }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n workplaces,\n }));\n })\n .catch(() => {});\n\n graphqlSdk\n .listStatusChanges()\n .then(({ statusChanges }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges: sortStatusChagnges(statusChanges),\n }));\n })\n .catch(() => {});\n }\n if (widgetSettings?.workplacesIds && gqlWsClient) {\n widgetSettings.workplacesIds.forEach((workplaceId) => {\n gqlWsClient.subscribe<WorkplaceEventSubscriptionPayload>(\n print(WorkplaceEventDocument),\n { id: workplaceId },\n ({ event, subject }) => {\n if (event === WorkplaceEvent.StatusChangeCreated) {\n const statusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => {\n const workplaceStatusChanges = current?.statusChanges?.filter(\n (statusChange) => statusChange.workplaceId === workplaceId,\n );\n const lastStatusChange = workplaceStatusChanges[workplaceStatusChanges.length - 1];\n\n if (lastStatusChange) {\n lastStatusChange.finishedAt = statusChange.startedAt;\n }\n return {\n ...(current || {}),\n statusChanges: [...current.statusChanges, statusChange],\n };\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 }\n },\n );\n });\n }\n }, [data, graphqlSdk, gqlWsClient, widgetSettings]);\n\n const handleSettingsChange = useCallback(\n (settings: WidgetSettings) => {\n setWidgetSettings({ ...settings });\n },\n [setWidgetSettings],\n );\n\n return (\n <BaseWidget\n {...widgetProps}\n lang={lang}\n locales={locales}\n data={widgetData}\n settings={settings}\n gqlClients={{ graphqlSdk, gqlWsClient }}\n onSettingsChange={handleSettingsChange}\n WidgetView={WidgetView}\n getSettingsFormProps={getSettingsFormProps}\n SettingsFormContent={SettingsFormContent}\n version={LIBRARY_VERSION}\n data-testid=\"workplaces-state-timelines-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 = 'workplacesStateTimelinesWidget';\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 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 return `${name} — ${t('titleWorkplaces', lang, { count: workplaces.length })}`;\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-state-timelines-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/helpers.ts","../src/components/TimelineLoader/index.tsx","../src/components/Timeline/styled.ts","../src/components/Timeline/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.9';\n","import { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { TabContext, TabList, TabPanel } from '@mui/lab';\nimport { Tab, TextField } from '@mui/material';\nimport { SortableSelect } from 'andoncloud-dashboard-toolkit';\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('workplaces');\n\n // -- Translation --\n const { t } = useTranslation();\n\n return (\n <TabContext value={selectedTab}>\n <TabList onChange={(_, value) => setSelectedTab(value)} centered>\n <Tab label={t('workplacesStateTimelinesWidget.workplaces')} value=\"workplaces\" />\n <Tab label={t('workplacesStateTimelinesWidget.advanced')} value=\"advanced\" />\n </TabList>\n\n <TabPanel value=\"workplaces\">\n <SortableSelect\n placeholder={`${t('workplacesStateTimelinesWidget.selectAndArrangeTheOrder')}...`}\n options={data.workplaces?.map(({ id, name }) => ({ label: name, value: id }))}\n selected={formProps.values.workplacesIds}\n onChange={(selected) => formProps.setFieldValue('workplacesIds', [...selected])}\n />\n </TabPanel>\n\n <TabPanel value=\"advanced\">\n <TextField\n name=\"customTitle\"\n label={t('workplacesStateTimelinesWidget.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 { AndonLightColor, ListStatusChanges_StatusChange, NormalizedShift } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nexport const durationSeconds = (\n shift: NormalizedShift,\n statusChange: ListStatusChanges_StatusChange,\n currentDate: Date,\n) => {\n const startedAt = shift.startedAt.isAfter(statusChange.startedAt) ? shift.startedAt : dayjs(statusChange.startedAt);\n\n if (startedAt && statusChange.finishedAt) {\n return Math.abs(startedAt.diff(dayjs(statusChange.finishedAt), 'seconds'));\n }\n return Math.abs(dayjs(currentDate).diff(startedAt, 'seconds'));\n};\n\nexport const mapTimelineColor = (color: AndonLightColor): string => {\n switch (color) {\n case 'green':\n return '#2ACB42';\n case 'red':\n return '#FF453A';\n case 'yellow':\n return '#FFC12F';\n default:\n return '#525860';\n }\n};\n","import ContentLoader from 'react-content-loader';\n\nconst TimelineLoader = () => (\n <ContentLoader\n data-testid=\"timeline-loading\"\n height=\"28\"\n width=\"100%\"\n speed={1.5}\n backgroundColor=\"#3d3d3d\"\n foregroundColor=\"#ffffff\"\n >\n <rect x=\"4%\" y=\"10\" ry=\"6\" width=\"92%\" height=\"14\" />\n </ContentLoader>\n);\n\nexport default TimelineLoader;\n","import { styled } from '@mui/material/styles';\nimport { AndonLightColor } from 'andoncloud-dashboard-toolkit';\n\nimport { mapTimelineColor } from '@/helpers';\n\nexport interface TimelineElementProps {\n percentWidth: number;\n color?: AndonLightColor;\n}\n\nexport const TimelineRow = styled('div')({\n display: 'flex',\n flexGrow: 1,\n alignItems: 'center',\n padding: '10px 0',\n background: '#252A32',\n '&:nth-of-type(2n)': {\n background: '#30353d',\n },\n});\n\nexport const TimelineWrapper = styled('div')({\n display: 'flex',\n margin: '6px 0',\n zIndex: 3,\n flexDirection: 'row',\n height: '20px',\n width: '100%',\n overflow: 'hidden',\n borderRadius: '4px',\n backgroundColor: 'rgba(0, 0, 0, 0.2)',\n});\n\nexport const TimelineTimeInfoContainer = styled('div')({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n});\n\nexport const TimelineTimeInfo = styled('span')({\n margin: '0 1.5em',\n fontSize: '12px',\n fontWeight: 500,\n lineHeight: '12px',\n color: 'rgba(255, 255, 255, 0.5)',\n});\n\nexport const TimelineElement = styled('div')<TimelineElementProps>(({ percentWidth, color }) => ({\n flexBasis: `${percentWidth}%`,\n flexShrink: 0,\n backgroundColor: mapTimelineColor(color as AndonLightColor),\n '&:first-of-type': {\n borderTopLeftRadius: '4px',\n borderBottomLeftRadius: '4px',\n },\n}));\n","import { Fragment, useCallback, useEffect, useState } from 'react';\n\nimport { Typography } from '@mui/material';\nimport { ListStatusChanges_StatusChange, NormalizedShift } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\nimport isBetween from 'dayjs/plugin/isBetween';\n\nimport { durationSeconds } from '@/helpers';\n\ndayjs.extend(isBetween);\n\nimport TimelineLoader from '../TimelineLoader';\n\nimport { TimelineElement, TimelineRow, TimelineTimeInfo, TimelineWrapper } from './styled';\n\nexport interface TimelineProps {\n title: string;\n shift: NormalizedShift | null;\n statusChanges: ListStatusChanges_StatusChange[];\n loading?: boolean;\n}\n\nconst Timeline: React.FC<TimelineProps> = ({ title, shift, statusChanges, loading }) => {\n const [shiftStatusChanges, setShiftStatusChanges] = useState<ListStatusChanges_StatusChange[]>([]);\n const calculateShiftDuration = useCallback(() => {\n return shift ? Math.abs(shift.startedAt.diff(shift.finishedAt, 'seconds')) : 0;\n }, [shift]);\n const isShiftStatusChange = useCallback(\n (statusChange: ListStatusChanges_StatusChange) => {\n const startedAt = dayjs(statusChange.startedAt);\n const finishedAt = statusChange.finishedAt ? dayjs(statusChange.finishedAt) : null;\n\n if (shift) {\n return (\n startedAt.isBetween(shift.startedAt, shift.finishedAt) ||\n finishedAt?.isBetween(shift.startedAt, shift.finishedAt) ||\n (startedAt.isBefore(shift.startedAt) && !finishedAt)\n );\n }\n return false;\n },\n [shift],\n );\n const [shiftDuration, setShiftDuration] = useState<number>(() => calculateShiftDuration());\n\n useEffect(() => {\n setShiftDuration(calculateShiftDuration());\n }, [shift, calculateShiftDuration]);\n\n useEffect(() => {\n setShiftStatusChanges(statusChanges.filter((statusChange) => isShiftStatusChange(statusChange)));\n }, [statusChanges, isShiftStatusChange]);\n\n if (loading) return <TimelineLoader />;\n\n return (\n <TimelineRow>\n <Typography\n sx={{\n display: title ? 'block' : 'none',\n flexBasis: '25%',\n marginLeft: '20px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n color: 'white',\n }}\n >\n {title}\n </Typography>\n {shift && (\n <Fragment>\n <TimelineTimeInfo>{shift.startedAt.format('HH:mm')}</TimelineTimeInfo>\n <TimelineWrapper data-testid=\"timeline\">\n {shiftStatusChanges?.map(\n (status) =>\n status.reason.statusColor && (\n <TimelineElement\n data-testid={`timeline-element-${status.id}-color-${status.reason.statusColor}`}\n key={`${status.id}${status.author.id}`}\n color={status.reason.statusColor}\n percentWidth={Math.min((durationSeconds(shift, status, new Date()) / shiftDuration) * 100, 100)}\n />\n ),\n )}\n </TimelineWrapper>\n <TimelineTimeInfo>{shift.finishedAt.format('HH:mm')}</TimelineTimeInfo>\n </Fragment>\n )}\n </TimelineRow>\n );\n};\n\nexport default Timeline;\n","import { useEffect, useState } from 'react';\n\nimport { Box } from '@mui/material';\nimport { getCurrentShift, NormalizedShift, normalizeShifts } from 'andoncloud-dashboard-toolkit';\nimport dayjs from 'dayjs';\n\nimport { WidgetViewProps } from '@/types';\n\nimport Timeline from '../Timeline';\n\nconst WidgetView: React.FC<WidgetViewProps> = ({ data, settings }) => {\n const [currentShift, setCurrentShift] = useState<NormalizedShift | null>(null);\n const getTitle = (workplaceId: string) => {\n const workplaces = data.workplaces;\n\n return settings?.workplacesIds?.length === 1\n ? ''\n : workplaces?.find((workplace) => workplace.id === workplaceId)?.name || '';\n };\n\n useEffect(() => {\n const updateCurrentShift = () => {\n const currentDate = dayjs();\n\n setCurrentShift(getCurrentShift(currentDate, normalizeShifts(data?.shifts || [], currentDate)));\n };\n const intervalId = setInterval(() => updateCurrentShift(), 10 * 1000);\n\n updateCurrentShift();\n\n return () => {\n clearInterval(intervalId);\n };\n }, [data?.shifts]);\n\n return (\n <Box display=\"flex\" flexDirection=\"column\" height=\"100%\">\n {settings?.workplacesIds.map((workplaceId) => (\n <Timeline\n key={workplaceId}\n title={getTitle(workplaceId)}\n shift={currentShift}\n statusChanges={data.statusChanges?.filter((statusChange) => statusChange.workplaceId === workplaceId) || []}\n loading={data === undefined}\n />\n ))}\n </Box>\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('workplacesStateTimelinesWidget.thisFieldIsRequired'),\n },\n });\n return {\n initialValues: {\n customTitle: '',\n workplacesIds: [],\n },\n validationSchema: yup.object({\n workplacesIds: yup.array().of(yup.string()).required(),\n }),\n };\n};\n","import { useCallback, useEffect, useState } from 'react';\n\nimport {\n ListStatusChanges_StatusChange,\n StatusChange,\n useGqlClients,\n WidgetProps,\n WorkplaceEvent,\n WorkplaceEventDocument,\n WorkplaceEventSubscriptionPayload,\n} from 'andoncloud-dashboard-toolkit';\nimport { BaseWidget } from 'andoncloud-widget-base';\nimport dayjs from 'dayjs';\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>> = ({\n url,\n wsUrl,\n lang,\n data,\n settings,\n ...widgetProps\n}) => {\n const { graphqlSdk, gqlWsClient } = useGqlClients({ url, wsUrl, lang });\n const [widgetData, setWidgetData] = useState<WidgetData | undefined>(data);\n const [widgetSettings, setWidgetSettings] = useState<WidgetSettings | undefined>(settings);\n\n const sortStatusChagnges = (items: ListStatusChanges_StatusChange[]): ListStatusChanges_StatusChange[] => {\n return items.sort((item1, item2) => {\n if (item1.finishedAt && item2.finishedAt) return dayjs(item1.finishedAt).diff(dayjs(item2.finishedAt));\n return item1.finishedAt ? -1 : 1;\n });\n };\n\n useEffect(() => {\n if (!data && graphqlSdk) {\n graphqlSdk\n .listShifts()\n .then(({ shifts }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n shifts,\n }));\n })\n .catch(() => {});\n\n graphqlSdk\n .listWorkplaces()\n .then(({ workplaces }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n workplaces,\n }));\n })\n .catch(() => {});\n\n graphqlSdk\n .listStatusChanges()\n .then(({ statusChanges }) => {\n return setWidgetData((current: WidgetData) => ({\n ...(current || {}),\n statusChanges: sortStatusChagnges(statusChanges),\n }));\n })\n .catch(() => {});\n }\n if (widgetSettings?.workplacesIds && gqlWsClient) {\n widgetSettings.workplacesIds.forEach((workplaceId) => {\n gqlWsClient.subscribe<WorkplaceEventSubscriptionPayload>(\n print(WorkplaceEventDocument),\n { id: workplaceId },\n ({ event, subject }) => {\n if (event === WorkplaceEvent.StatusChangeCreated) {\n const statusChange = subject as StatusChange;\n\n setWidgetData((current: WidgetData) => {\n const workplaceStatusChanges = current?.statusChanges?.filter(\n (statusChange) => statusChange.workplaceId === workplaceId,\n );\n const lastStatusChange = workplaceStatusChanges[workplaceStatusChanges.length - 1];\n\n if (lastStatusChange) {\n lastStatusChange.finishedAt = statusChange.startedAt;\n }\n return {\n ...(current || {}),\n statusChanges: [...current.statusChanges, statusChange],\n };\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 }\n },\n );\n });\n }\n }, [data, graphqlSdk, gqlWsClient, widgetSettings]);\n\n const handleSettingsChange = useCallback(\n (settings: WidgetSettings) => {\n setWidgetSettings({ ...settings });\n },\n [setWidgetSettings],\n );\n\n return (\n <BaseWidget\n {...widgetProps}\n lang={lang}\n locales={locales}\n data={widgetData}\n settings={settings}\n gqlClients={{ graphqlSdk, gqlWsClient }}\n onSettingsChange={handleSettingsChange}\n WidgetView={WidgetView}\n getSettingsFormProps={getSettingsFormProps}\n SettingsFormContent={SettingsFormContent}\n version={LIBRARY_VERSION}\n data-testid=\"workplaces-state-timelines-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 = 'workplacesStateTimelinesWidget';\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 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 return `${name} — ${t('titleCurrentShift', lang)}, ${t('titleWorkplaces', lang, { count: workplaces.length })}`;\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-state-timelines-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-state-timelines-widget",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Made with create-andoncloud-widget",
5
5
  "author": "Adrian Olszewski",
6
6
  "license": "MIT",