UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

660 lines (659 loc) • 22 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { c } from "react/compiler-runtime"; import "history"; import { useReducer, useEffect, useState } from "react"; import { TasksEnabledContext, TasksNavigationContext, TasksContext, TasksUpsellContext } from "sanity/_singletons"; import "@sanity/icons/ArrowLeft"; import "@sanity/icons/Launch"; import { useToast } from "@sanity/ui"; import "styled-components"; import "./index.js"; import "react-i18next"; import "@sanity/util/paths"; import "react-fast-compare"; import { useFeatureEnabled, FEATURES, useWorkspace, TASKS_SIDEBAR_SEARCH_PARAM, TASKS_VIEW_MODE_SEARCH_PARAM, TASKS_SELECTED_TASK_SEARCH_PARAM, TaskLinkCopied, TaskLinkOpened, useAddonDataset, useUpsellContext, getDialogPropsFromContext, UpsellDialog, useTasksEnabled, AddonDatasetProvider } from "./index2.js"; import "react-rx"; import { of, catchError } from "rxjs"; import "rxjs/operators"; import "./createAgentBundlesStore.js"; import { getPublishedId } from "@sanity/client/csm"; import "quick-lru"; import "lodash-es/throttle.js"; import "lodash-es/isEqual.js"; import { useTelemetry } from "@sanity/telemetry/react"; import "@sanity/icons/Document"; import "@sanity/icons/Image"; import { uuid } from "@sanity/uuid"; import "@sanity/color"; import "color2k"; import "lodash-es/isString.js"; import "@sanity/icons/Copy"; import "@sanity/icons/Clipboard"; import "@sanity/types"; import "@portabletext/editor"; import "@sanity/icons/ChevronRight"; import "@sanity/icons/Revert"; import "@sanity/ui/theme"; import "date-fns/differenceInDays"; import "date-fns/differenceInHours"; import "date-fns/differenceInMinutes"; import "date-fns/differenceInMonths"; import "date-fns/differenceInSeconds"; import "date-fns/differenceInWeeks"; import "date-fns/differenceInYears"; import "@sanity/icons/AddCircle"; import "@sanity/icons/Calendar"; import "@sanity/icons/Circle"; import "@sanity/icons/Close"; import "@sanity/icons/Edit"; import "@sanity/icons/Publish"; import "@sanity/icons/Timeline"; import "@sanity/icons/Trash"; import "@sanity/icons/Unpublish"; import "@sanity/icons/ArrowDown"; import "@sanity/icons/ArrowRight"; import "@sanity/util/legacyDateFormat"; import "./version.js"; import "@sanity/diff-patch"; import "@sanity/icons/ErrorOutline"; import "@sanity/diff"; import "mendoza"; import "@sanity/icons/InfoOutline"; import "@sanity/icons/WarningOutline"; import "@portabletext/sanity-bridge"; import "@sanity/id-utils"; import { useRouter } from "sanity/router"; import "@sanity/icons/ChevronDown"; import "date-fns/addHours"; import "date-fns/startOfHour"; import "@sanity/icons/Bolt"; import "@sanity/icons/Clock"; import "@sanity/icons/Dot"; import "@sanity/icons/EarthGlobe"; import "date-fns/format"; import "date-fns/isValid"; import "date-fns/parse"; import "lodash-es/flatten.js"; import "date-fns/getMinutes"; import "date-fns/parseISO"; import "date-fns/setMinutes"; import "@sanity/icons/EarthAmericas"; import "lodash-es/noop.js"; import "@sanity/icons/Search"; import "motion/react"; import "lodash-es/pick.js"; import "lodash-es/get.js"; import "@algorithm.ts/lcs"; import "lodash-es/intersection.js"; import "json-stable-stringify"; import "shallow-equals"; import "scroll-into-view-if-needed"; import "@sanity/schema/_internal"; import "lodash-es/groupBy.js"; import "lodash-es/sortBy.js"; import "lodash-es/compact.js"; import "lodash-es/keyBy.js"; import "lodash-es/partition.js"; import "lodash-es/toLower.js"; import "lodash-es/union.js"; import "lodash-es/uniq.js"; import "lodash-es/words.js"; import "lodash-es/isFinite.js"; import "@sanity/icons/Add"; import "observable-callback"; import "@sanity/util/content"; import "@sanity/icons/BulbOutline"; import "@sanity/icons/Unknown"; import "@sanity/icons/ToggleArrowRight"; import "lodash-es/isPlainObject.js"; import "@sanity/insert-menu"; import "@dnd-kit/sortable"; import "@sanity/icons/DragHandle"; import "@sanity/icons/AddDocument"; import "@sanity/icons/InsertAbove"; import "@sanity/icons/InsertBelow"; import "@tanstack/react-virtual"; import "lodash-es/startCase.js"; import "speakingurl"; import "@sanity/icons/Reset"; import "@sanity/icons/Sync"; import "@sanity/asset-utils"; import "@sanity/icons/AccessDenied"; import "@sanity/icons/HelpCircle"; import "@sanity/image-url"; import "@portabletext/react"; import "@sanity/icons"; import "@sanity/icons/Link"; import "react-is"; import "lodash-es/pickBy.js"; import "@sanity/client"; import "swr"; import "@sanity/icons/Download"; import "@sanity/icons/Upload"; import "@sanity/icons/BinaryDocument"; import "@sanity/icons/Lock"; import "lodash-es/castArray.js"; import "nanoid"; import "use-hot-module-reload"; import "@sanity/icons/EllipsisHorizontal"; import "@sanity/icons/EyeOpen"; import "rxjs-mergemap-array"; import "@sanity/mutator"; import "react-focus-lock"; import "lodash-es/memoize.js"; import "lodash-es/sortedIndex.js"; import "lodash-es/difference.js"; import "lodash-es/identity.js"; import "lodash-es/values.js"; import "@sanity/comlink"; import "lodash-es/omit.js"; import "@isaacs/ttlcache"; import "@sanity/schema"; import "@sanity/util/client"; import "@sanity/util/concurrency-limiter"; import "lodash-es/uniqBy.js"; import "json-reduce"; import "rxjs-exhaustmap-with-trailing"; import "dataloader"; import "raf"; import "groq-js"; import "use-sync-external-store/with-selector"; import debounce from "lodash-es/debounce.js"; import "clsx"; import "@sanity/icons/LinkRemoved"; import "lodash-es/findIndex.js"; import "@sanity/diff-match-patch"; import "@sanity/icons/ChevronUp"; import "@sanity/icons/Feedback"; import "@xstate/react"; import "xstate"; import "@sanity/icons/FaceHappy"; import "@sanity/icons/FaceIndifferent"; import "@sanity/icons/FaceSad"; import "@sentry/react"; import "date-fns/isBefore"; import "date-fns/startOfMinute"; import "@sanity/icons/Documents"; import "@portabletext/toolkit"; import "@sanity/icons/User"; import "@sanity/icons/CheckmarkCircle"; import "lodash-es/deburr.js"; import "@sanity/icons/ChevronLeft"; import "@sanity/icons/Checkmark"; import "@sanity/logos"; import "is-network-error"; import "lodash-es/escapeRegExp.js"; import "@sanity/icons/Desktop"; import "@sanity/icons/Moon"; import "@sanity/icons/Sun"; import "lodash-es/isEmpty.js"; import "react-dom/server"; import "@sanity/icons/Controls"; import "@sanity/icons/Sort"; import "lodash-es/capitalize.js"; import "@sanity/icons/Undo"; import "@sanity/icons/Menu"; import "@sanity/icons/AddUser"; import "@sanity/icons/Cog"; import "@sanity/icons/Users"; import "semver"; import "@sanity/icons/Github"; import "@sanity/icons/Refresh"; import "@sanity/icons/Leave"; import "lodash-es/last.js"; import "react-dom/client"; import "date-fns/addWeeks"; import "date-fns/isAfter"; function TasksEnabledProvider(t0) { const $ = c(6), { children } = t0, { enabled, isLoading, error } = useFeatureEnabled(FEATURES.sanityTasks), isWorkspaceEnabled = useWorkspace().tasks?.enabled; let t1; bb0: { if (!isWorkspaceEnabled || isLoading || error) { let t23; $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t23 = { enabled: !1, mode: null }, $[0] = t23) : t23 = $[0], t1 = t23; break bb0; } const t22 = enabled ? "default" : "upsell"; let t3; $[1] !== t22 ? (t3 = { enabled: !0, mode: t22 }, $[1] = t22, $[2] = t3) : t3 = $[2], t1 = t3; } const value = t1; let t2; return $[3] !== children || $[4] !== value ? (t2 = /* @__PURE__ */ jsx(TasksEnabledContext.Provider, { value, children }), $[3] = children, $[4] = value, $[5] = t2) : t2 = $[5], t2; } const initialState = { viewMode: "list", selectedTask: null, activeTabId: "assigned", duplicateTaskValues: null, isOpen: !1 }; function reducer(state, action) { switch (action.type) { case "TOGGLE_TASKS_VIEW": return action.payload ? { ...state, isOpen: action.payload } : { ...initialState, isOpen: action.payload }; case "CREATE_TASK": return { ...state, viewMode: "create", selectedTask: uuid() }; case "EDIT_TASK": return { ...state, viewMode: "edit", selectedTask: action.payload.id }; case "EDIT_DRAFT": return { ...state, viewMode: "draft", selectedTask: action.payload.id }; case "DUPLICATE_TASK": return { ...state, viewMode: "duplicate", selectedTask: uuid(), duplicateTaskValues: action.payload.duplicateTaskValues }; case "SET_ACTIVE_TAB": return { ...state, viewMode: "list", activeTabId: action.payload }; case "NAVIGATE_TO_LIST": return { ...state, viewMode: "list" }; default: return state; } } const TasksNavigationProvider = (t0) => { const $ = c(23), { children } = t0, [state, dispatch] = useReducer(reducer, initialState), router = useRouter(), toast = useToast(), telemetry = useTelemetry(); let t1; $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t1 = (viewMode) => { bb2: switch (viewMode.type) { case "list": { dispatch({ type: "NAVIGATE_TO_LIST" }); break bb2; } case "create": { dispatch({ type: "CREATE_TASK" }); break bb2; } case "edit": { dispatch({ type: "EDIT_TASK", payload: { id: viewMode.id } }); break bb2; } case "duplicate": { dispatch({ type: "DUPLICATE_TASK", payload: { duplicateTaskValues: viewMode.duplicateTaskValues } }); break bb2; } case "draft": { dispatch({ type: "EDIT_DRAFT", payload: { id: viewMode.id } }); break bb2; } } }, $[0] = t1) : t1 = $[0]; const setViewMode = t1; let t2; $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = (tabId) => { dispatch({ type: "SET_ACTIVE_TAB", payload: tabId }); }, $[1] = t2) : t2 = $[1]; const setActiveTab = t2; let t3; $[2] !== router ? (t3 = () => { dispatch({ type: "TOGGLE_TASKS_VIEW", payload: !1 }), router.navigate({ stickyParams: { ...router.stickyParams, [TASKS_SIDEBAR_SEARCH_PARAM]: null, [TASKS_VIEW_MODE_SEARCH_PARAM]: null, [TASKS_SELECTED_TASK_SEARCH_PARAM]: null } }); }, $[2] = router, $[3] = t3) : t3 = $[3]; const handleCloseTasks = t3; let t4; $[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t4 = () => { dispatch({ type: "TOGGLE_TASKS_VIEW", payload: !0 }); }, $[4] = t4) : t4 = $[4]; const handleOpenTasks = t4; let t5; $[5] !== state.selectedTask || $[6] !== state.viewMode || $[7] !== telemetry || $[8] !== toast ? (t5 = () => { const url = new URL(window.location.href); url.searchParams.set(TASKS_SIDEBAR_SEARCH_PARAM, "tasks"), url.searchParams.set(TASKS_VIEW_MODE_SEARCH_PARAM, state.viewMode), state.selectedTask && url.searchParams.set(TASKS_SELECTED_TASK_SEARCH_PARAM, state.selectedTask), navigator.clipboard.writeText(url.toString()).then(() => { telemetry.log(TaskLinkCopied); }).catch(() => { toast.push({ closable: !0, status: "error", title: "Failed to copy link to clipboard" }); }); }, $[5] = state.selectedTask, $[6] = state.viewMode, $[7] = telemetry, $[8] = toast, $[9] = t5) : t5 = $[9]; const handleCopyLinkToTask = t5, sidebar = router.stickyParams[TASKS_SIDEBAR_SEARCH_PARAM], viewMode_0 = router.stickyParams[TASKS_VIEW_MODE_SEARCH_PARAM], selectedTask = router.stickyParams[TASKS_SELECTED_TASK_SEARCH_PARAM]; let t6, t7; $[10] !== selectedTask || $[11] !== sidebar || $[12] !== telemetry || $[13] !== viewMode_0 ? (t6 = () => { sidebar === "tasks" && (dispatch({ type: "TOGGLE_TASKS_VIEW", payload: !0 }), viewMode_0 === "edit" && selectedTask && (dispatch({ type: "EDIT_TASK", payload: { id: selectedTask } }), telemetry.log(TaskLinkOpened))); }, t7 = [selectedTask, sidebar, telemetry, viewMode_0], $[10] = selectedTask, $[11] = sidebar, $[12] = telemetry, $[13] = viewMode_0, $[14] = t6, $[15] = t7) : (t6 = $[14], t7 = $[15]), useEffect(t6, t7); let t8; $[16] !== handleCloseTasks || $[17] !== handleCopyLinkToTask || $[18] !== state ? (t8 = { state, setViewMode, setActiveTab, handleCloseTasks, handleOpenTasks, handleCopyLinkToTask }, $[16] = handleCloseTasks, $[17] = handleCopyLinkToTask, $[18] = state, $[19] = t8) : t8 = $[19]; const value = t8; let t9; return $[20] !== children || $[21] !== value ? (t9 = /* @__PURE__ */ jsx(TasksNavigationContext.Provider, { value, children }), $[20] = children, $[21] = value, $[22] = t9) : t9 = $[22], t9; }; function createTasksSet(tasks) { return tasks.reduce((acc, task) => ({ ...acc, [task._id]: task }), {}); } function tasksReducer(state, action) { switch (action.type) { case "TASKS_SET": { const tasksById = createTasksSet(action.tasks); return { ...state, tasks: tasksById }; } case "TASK_ADDED": { const nextTaskResult = action.payload, nextTaskValue = nextTaskResult, nextTask = { [nextTaskResult._id]: { ...state.tasks[nextTaskResult._id], ...nextTaskValue, _state: nextTaskResult._state || void 0, // If the task is created optimistically, it won't have a createdAt date as this is set on the server. // However, we need to set a createdAt date to be able to sort the tasks correctly. // Therefore, we set the createdAt date to the current date here if it's missing while creating the task. // Once the task is created and received from the server, the createdAt date will be updated to the correct value. _createdAt: nextTaskResult._createdAt || (/* @__PURE__ */ new Date()).toISOString() } }; return { ...state, tasks: { ...state.tasks, ...nextTask } }; } case "TASK_RECEIVED": { const nextTaskResult = action.payload; return { ...state, tasks: { ...state.tasks, [nextTaskResult._id]: nextTaskResult } }; } case "TASK_DELETED": { const { [action.id]: _, ...restTasks } = state.tasks; return { ...state, tasks: restTasks }; } case "TASK_UPDATED": { const updatedTask = action.payload, id = updatedTask._id, nextTask = { // Add existing task data ...state.tasks[id], // Add incoming task data ...updatedTask }; return { ...state, tasks: { ...state.tasks, [id]: nextTask } }; } default: return state; } } const INITIAL_STATE = { tasks: {} }, LISTEN_OPTIONS = { events: ["welcome", "mutation", "reconnect"], includeResult: !0, visibility: "query", includeAllVersions: !0, tag: "tasks-store" }, SORT_FIELD = "_createdAt", SORT_ORDER = "desc", QUERY_FILTERS = ['_type == "tasks.task"'], QUERY_PROJECTION = `{ ..., }`, QUERY_SORT_ORDER = `order(${SORT_FIELD} ${SORT_ORDER})`, QUERY = `*[${QUERY_FILTERS.join(" && ")}] ${QUERY_PROJECTION} | ${QUERY_SORT_ORDER}`; function useTasksStore(opts) { const $ = c(24), { client } = useAddonDataset(), { documentId } = opts, [state, dispatch] = useReducer(tasksReducer, INITIAL_STATE), [isLoading, setIsLoading] = useState(client !== null), [error, setError] = useState(null); let t0; $[0] !== documentId ? (t0 = documentId ? getPublishedId(documentId) : null, $[0] = documentId, $[1] = t0) : t0 = $[1]; let t1; $[2] !== t0 ? (t1 = { documentId: t0 }, $[2] = t0, $[3] = t1) : t1 = $[3]; const params = t1; let t2; $[4] !== client || $[5] !== params ? (t2 = async () => { if (!client) { setIsLoading(!1); return; } try { const res = await client.fetch(QUERY, params); dispatch({ type: "TASKS_SET", tasks: res }), setIsLoading(!1); } catch (t32) { setError(t32); } }, $[4] = client, $[5] = params, $[6] = t2) : t2 = $[6]; const initialFetch = t2; let t3; $[7] !== initialFetch ? (t3 = async (event) => { if (event.type === "welcome" && (setIsLoading(!0), await initialFetch(), setIsLoading(!1)), event.type === "reconnect" && setIsLoading(!0), event.type === "mutation") { if (event.transition === "appear") { const nextTask = event.result; nextTask && dispatch({ type: "TASK_RECEIVED", payload: nextTask }); } if (event.transition === "disappear" && dispatch({ type: "TASK_DELETED", id: event.documentId }), event.transition === "update") { const updatedTask = event.result; updatedTask && dispatch({ type: "TASK_UPDATED", payload: updatedTask }); } } }, $[7] = initialFetch, $[8] = t3) : t3 = $[8]; const handleListenerEvent = t3; let t4; bb0: { if (!client) { let t53; $[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t53 = of(), $[9] = t53) : t53 = $[9], t4 = t53; break bb0; } let t52; if ($[10] !== client.observable || $[11] !== params) { let t62; $[13] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t62 = (err_0) => (setError(err_0), of(err_0)), $[13] = t62) : t62 = $[13], t52 = client.observable.listen(QUERY, params, LISTEN_OPTIONS).pipe(catchError(t62)), $[10] = client.observable, $[11] = params, $[12] = t52; } else t52 = $[12]; t4 = t52; } const listener$ = t4; let t5, t6; $[14] !== handleListenerEvent || $[15] !== listener$ ? (t5 = () => { const sub = listener$.subscribe(handleListenerEvent); return () => { sub?.unsubscribe(); }; }, t6 = [handleListenerEvent, listener$], $[14] = handleListenerEvent, $[15] = listener$, $[16] = t5, $[17] = t6) : (t5 = $[16], t6 = $[17]), useEffect(t5, t6); let t7; $[18] !== state.tasks ? (t7 = Object.values(state.tasks), $[18] = state.tasks, $[19] = t7) : t7 = $[19]; const tasksAsArray = t7; let t8; return $[20] !== error || $[21] !== isLoading || $[22] !== tasksAsArray ? (t8 = { data: tasksAsArray, dispatch, error, isLoading }, $[20] = error, $[21] = isLoading, $[22] = tasksAsArray, $[23] = t8) : t8 = $[23], t8; } const EMPTY_ARRAY = []; function TasksProvider(props) { const $ = c(11), { children } = props, [activeDocument, setActiveDocument] = useState(null); let t0; $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = {}, $[0] = t0) : t0 = $[0]; const { data: t1, isLoading } = useTasksStore(t0), data = t1 === void 0 ? EMPTY_ARRAY : t1; let t2; $[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t2 = debounce(setActiveDocument, 1e3), $[1] = t2) : t2 = $[1]; const debouncedSetActiveDocument = t2; let t3; $[2] !== data ? (t3 = data ?? [], $[2] = data, $[3] = t3) : t3 = $[3]; let t4; $[4] !== activeDocument || $[5] !== isLoading || $[6] !== t3 ? (t4 = { activeDocument, setActiveDocument: debouncedSetActiveDocument, isLoading, data: t3 }, $[4] = activeDocument, $[5] = isLoading, $[6] = t3, $[7] = t4) : t4 = $[7]; const value = t4; let t5; return $[8] !== children || $[9] !== value ? (t5 = /* @__PURE__ */ jsx(TasksContext.Provider, { value, children }), $[8] = children, $[9] = value, $[10] = t5) : t5 = $[10], t5; } function TasksUpsellProvider(props) { const $ = c(9); let t0; $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = { dataUri: "/journey/tasks", feature: "tasks" }, $[0] = t0) : t0 = $[0]; const contextValue = useUpsellContext(t0), t1 = props.children; let t2; $[1] !== contextValue ? (t2 = getDialogPropsFromContext(contextValue), $[1] = contextValue, $[2] = t2) : t2 = $[2]; let t3; $[3] !== t2 ? (t3 = /* @__PURE__ */ jsx(UpsellDialog, { ...t2 }), $[3] = t2, $[4] = t3) : t3 = $[4]; let t4; return $[5] !== contextValue || $[6] !== props.children || $[7] !== t3 ? (t4 = /* @__PURE__ */ jsxs(TasksUpsellContext.Provider, { value: contextValue, children: [ t1, t3 ] }), $[5] = contextValue, $[6] = props.children, $[7] = t3, $[8] = t4) : t4 = $[8], t4; } const TasksStudioLayoutInner = (props) => { const $ = c(10), { enabled, mode } = useTasksEnabled(); if (!enabled) { let t02; return $[0] !== props ? (t02 = props.renderDefault(props), $[0] = props, $[1] = t02) : t02 = $[1], t02; } let t0; $[2] !== props ? (t0 = props.renderDefault(props), $[2] = props, $[3] = t0) : t0 = $[3]; let t1; $[4] !== t0 ? (t1 = /* @__PURE__ */ jsx(TasksProvider, { children: /* @__PURE__ */ jsx(TasksNavigationProvider, { children: t0 }) }), $[4] = t0, $[5] = t1) : t1 = $[5]; const children = t1; if (mode === "upsell") { let t22; return $[6] !== children ? (t22 = /* @__PURE__ */ jsx(AddonDatasetProvider, { children: /* @__PURE__ */ jsx(TasksUpsellProvider, { children }) }), $[6] = children, $[7] = t22) : t22 = $[7], t22; } let t2; return $[8] !== children ? (t2 = /* @__PURE__ */ jsx(AddonDatasetProvider, { children }), $[8] = children, $[9] = t2) : t2 = $[9], t2; }; function TasksStudioLayout(props) { const $ = c(2); let t0; return $[0] !== props ? (t0 = /* @__PURE__ */ jsx(TasksEnabledProvider, { children: /* @__PURE__ */ jsx(TasksStudioLayoutInner, { ...props }) }), $[0] = props, $[1] = t0) : t0 = $[1], t0; } export { TasksStudioLayout }; //# sourceMappingURL=TasksStudioLayout.js.map