@burdenoff/microfe-planmagnet 2026.1008.2 → 2026.1008.4
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/_virtual/__vite-browser-external.js +0 -2
- package/dist/components/MarkdownEditor.js +0 -2
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +0 -2
- package/dist/node_modules/@apollo/client/errors/ServerError.js +0 -2
- package/dist/node_modules/@apollo/client/errors/utils.js +0 -2
- package/dist/node_modules/clsx/dist/clsx.js +0 -2
- package/dist/node_modules/d3-array/src/ascending.js +0 -2
- package/dist/node_modules/d3-array/src/bisect.js +0 -2
- package/dist/node_modules/d3-array/src/bisector.js +0 -2
- package/dist/node_modules/d3-array/src/descending.js +0 -2
- package/dist/node_modules/d3-array/src/max.js +0 -2
- package/dist/node_modules/d3-array/src/min.js +0 -2
- package/dist/node_modules/d3-array/src/number.js +0 -2
- package/dist/node_modules/d3-array/src/quantile.js +0 -2
- package/dist/node_modules/d3-array/src/quickselect.js +0 -2
- package/dist/node_modules/d3-array/src/range.js +0 -2
- package/dist/node_modules/d3-array/src/sort.js +0 -2
- package/dist/node_modules/d3-array/src/ticks.js +0 -2
- package/dist/node_modules/d3-color/src/color.js +0 -2
- package/dist/node_modules/d3-color/src/define.js +0 -2
- package/dist/node_modules/d3-format/src/defaultLocale.js +0 -2
- package/dist/node_modules/d3-format/src/exponent.js +0 -2
- package/dist/node_modules/d3-format/src/formatDecimal.js +0 -2
- package/dist/node_modules/d3-format/src/formatGroup.js +0 -2
- package/dist/node_modules/d3-format/src/formatNumerals.js +0 -2
- package/dist/node_modules/d3-format/src/formatPrefixAuto.js +0 -2
- package/dist/node_modules/d3-format/src/formatRounded.js +0 -2
- package/dist/node_modules/d3-format/src/formatSpecifier.js +0 -2
- package/dist/node_modules/d3-format/src/formatTrim.js +0 -2
- package/dist/node_modules/d3-format/src/formatTypes.js +0 -2
- package/dist/node_modules/d3-format/src/identity.js +0 -2
- package/dist/node_modules/d3-format/src/locale.js +0 -2
- package/dist/node_modules/d3-format/src/precisionFixed.js +0 -2
- package/dist/node_modules/d3-format/src/precisionPrefix.js +0 -2
- package/dist/node_modules/d3-format/src/precisionRound.js +0 -2
- package/dist/node_modules/d3-interpolate/src/array.js +0 -2
- package/dist/node_modules/d3-interpolate/src/basis.js +0 -2
- package/dist/node_modules/d3-interpolate/src/basisClosed.js +0 -2
- package/dist/node_modules/d3-interpolate/src/color.js +0 -2
- package/dist/node_modules/d3-interpolate/src/constant.js +0 -2
- package/dist/node_modules/d3-interpolate/src/date.js +0 -2
- package/dist/node_modules/d3-interpolate/src/number.js +0 -2
- package/dist/node_modules/d3-interpolate/src/numberArray.js +0 -2
- package/dist/node_modules/d3-interpolate/src/object.js +0 -2
- package/dist/node_modules/d3-interpolate/src/piecewise.js +0 -2
- package/dist/node_modules/d3-interpolate/src/rgb.js +0 -2
- package/dist/node_modules/d3-interpolate/src/round.js +0 -2
- package/dist/node_modules/d3-interpolate/src/string.js +0 -2
- package/dist/node_modules/d3-interpolate/src/value.js +0 -2
- package/dist/node_modules/d3-path/src/path.js +0 -2
- package/dist/node_modules/d3-scale/src/band.js +0 -2
- package/dist/node_modules/d3-scale/src/constant.js +0 -2
- package/dist/node_modules/d3-scale/src/continuous.js +0 -2
- package/dist/node_modules/d3-scale/src/diverging.js +0 -2
- package/dist/node_modules/d3-scale/src/identity.js +0 -2
- package/dist/node_modules/d3-scale/src/init.js +0 -2
- package/dist/node_modules/d3-scale/src/linear.js +0 -2
- package/dist/node_modules/d3-scale/src/log.js +0 -2
- package/dist/node_modules/d3-scale/src/nice.js +0 -2
- package/dist/node_modules/d3-scale/src/number.js +0 -2
- package/dist/node_modules/d3-scale/src/ordinal.js +0 -2
- package/dist/node_modules/d3-scale/src/pow.js +0 -2
- package/dist/node_modules/d3-scale/src/quantile.js +0 -2
- package/dist/node_modules/d3-scale/src/quantize.js +0 -2
- package/dist/node_modules/d3-scale/src/radial.js +0 -2
- package/dist/node_modules/d3-scale/src/sequential.js +0 -2
- package/dist/node_modules/d3-scale/src/sequentialQuantile.js +0 -2
- package/dist/node_modules/d3-scale/src/symlog.js +0 -2
- package/dist/node_modules/d3-scale/src/threshold.js +0 -2
- package/dist/node_modules/d3-scale/src/tickFormat.js +0 -2
- package/dist/node_modules/d3-scale/src/time.js +0 -2
- package/dist/node_modules/d3-scale/src/utcTime.js +0 -2
- package/dist/node_modules/d3-shape/src/area.js +0 -2
- package/dist/node_modules/d3-shape/src/array.js +0 -2
- package/dist/node_modules/d3-shape/src/constant.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/basis.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/basisClosed.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/basisOpen.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/bump.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/linear.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/linearClosed.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/monotone.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/natural.js +0 -2
- package/dist/node_modules/d3-shape/src/curve/step.js +0 -2
- package/dist/node_modules/d3-shape/src/line.js +0 -2
- package/dist/node_modules/d3-shape/src/math.js +0 -2
- package/dist/node_modules/d3-shape/src/noop.js +0 -2
- package/dist/node_modules/d3-shape/src/offset/expand.js +0 -2
- package/dist/node_modules/d3-shape/src/offset/none.js +0 -2
- package/dist/node_modules/d3-shape/src/offset/silhouette.js +0 -2
- package/dist/node_modules/d3-shape/src/offset/wiggle.js +0 -2
- package/dist/node_modules/d3-shape/src/order/none.js +0 -2
- package/dist/node_modules/d3-shape/src/path.js +0 -2
- package/dist/node_modules/d3-shape/src/point.js +0 -2
- package/dist/node_modules/d3-shape/src/stack.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/circle.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/cross.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/diamond.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/square.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/star.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/triangle.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol/wye.js +0 -2
- package/dist/node_modules/d3-shape/src/symbol.js +0 -2
- package/dist/node_modules/d3-time/src/day.js +0 -2
- package/dist/node_modules/d3-time/src/duration.js +0 -2
- package/dist/node_modules/d3-time/src/hour.js +0 -2
- package/dist/node_modules/d3-time/src/interval.js +0 -2
- package/dist/node_modules/d3-time/src/millisecond.js +0 -2
- package/dist/node_modules/d3-time/src/minute.js +0 -2
- package/dist/node_modules/d3-time/src/month.js +0 -2
- package/dist/node_modules/d3-time/src/second.js +0 -2
- package/dist/node_modules/d3-time/src/ticks.js +0 -2
- package/dist/node_modules/d3-time/src/week.js +0 -2
- package/dist/node_modules/d3-time/src/year.js +0 -2
- package/dist/node_modules/d3-time-format/src/defaultLocale.js +0 -2
- package/dist/node_modules/d3-time-format/src/locale.js +0 -2
- package/dist/node_modules/decimal.js-light/decimal.js +0 -2
- package/dist/node_modules/eventemitter3/index.js +0 -2
- package/dist/node_modules/fast-equals/dist/es/index.js +0 -2
- package/dist/node_modules/fflate/esm/browser.js +0 -2
- package/dist/node_modules/internmap/src/index.js +0 -2
- package/dist/node_modules/jszip/dist/jszip.min.js +0 -2
- package/dist/node_modules/lodash/_DataView.js +0 -2
- package/dist/node_modules/lodash/_Hash.js +0 -2
- package/dist/node_modules/lodash/_ListCache.js +0 -2
- package/dist/node_modules/lodash/_Map.js +0 -2
- package/dist/node_modules/lodash/_MapCache.js +0 -2
- package/dist/node_modules/lodash/_Promise.js +0 -2
- package/dist/node_modules/lodash/_Set.js +0 -2
- package/dist/node_modules/lodash/_SetCache.js +0 -2
- package/dist/node_modules/lodash/_Stack.js +0 -2
- package/dist/node_modules/lodash/_Symbol.js +0 -2
- package/dist/node_modules/lodash/_Uint8Array.js +0 -2
- package/dist/node_modules/lodash/_WeakMap.js +0 -2
- package/dist/node_modules/lodash/_apply.js +0 -2
- package/dist/node_modules/lodash/_arrayEach.js +0 -2
- package/dist/node_modules/lodash/_arrayEvery.js +0 -2
- package/dist/node_modules/lodash/_arrayFilter.js +0 -2
- package/dist/node_modules/lodash/_arrayIncludes.js +0 -2
- package/dist/node_modules/lodash/_arrayIncludesWith.js +0 -2
- package/dist/node_modules/lodash/_arrayLikeKeys.js +0 -2
- package/dist/node_modules/lodash/_arrayMap.js +0 -2
- package/dist/node_modules/lodash/_arrayPush.js +0 -2
- package/dist/node_modules/lodash/_arraySome.js +0 -2
- package/dist/node_modules/lodash/_asciiToArray.js +0 -2
- package/dist/node_modules/lodash/_assignValue.js +0 -2
- package/dist/node_modules/lodash/_assocIndexOf.js +0 -2
- package/dist/node_modules/lodash/_baseAssign.js +0 -2
- package/dist/node_modules/lodash/_baseAssignIn.js +0 -2
- package/dist/node_modules/lodash/_baseAssignValue.js +0 -2
- package/dist/node_modules/lodash/_baseClone.js +0 -2
- package/dist/node_modules/lodash/_baseCreate.js +0 -2
- package/dist/node_modules/lodash/_baseEach.js +0 -2
- package/dist/node_modules/lodash/_baseEvery.js +0 -2
- package/dist/node_modules/lodash/_baseExtremum.js +0 -2
- package/dist/node_modules/lodash/_baseFindIndex.js +0 -2
- package/dist/node_modules/lodash/_baseFlatten.js +0 -2
- package/dist/node_modules/lodash/_baseFor.js +0 -2
- package/dist/node_modules/lodash/_baseForOwn.js +0 -2
- package/dist/node_modules/lodash/_baseGet.js +0 -2
- package/dist/node_modules/lodash/_baseGetAllKeys.js +0 -2
- package/dist/node_modules/lodash/_baseGetTag.js +0 -2
- package/dist/node_modules/lodash/_baseGt.js +0 -2
- package/dist/node_modules/lodash/_baseHasIn.js +0 -2
- package/dist/node_modules/lodash/_baseIndexOf.js +0 -2
- package/dist/node_modules/lodash/_baseIsArguments.js +0 -2
- package/dist/node_modules/lodash/_baseIsEqual.js +0 -2
- package/dist/node_modules/lodash/_baseIsEqualDeep.js +0 -2
- package/dist/node_modules/lodash/_baseIsMap.js +0 -2
- package/dist/node_modules/lodash/_baseIsMatch.js +0 -2
- package/dist/node_modules/lodash/_baseIsNaN.js +0 -2
- package/dist/node_modules/lodash/_baseIsNative.js +0 -2
- package/dist/node_modules/lodash/_baseIsSet.js +0 -2
- package/dist/node_modules/lodash/_baseIsTypedArray.js +0 -2
- package/dist/node_modules/lodash/_baseIteratee.js +0 -2
- package/dist/node_modules/lodash/_baseKeys.js +0 -2
- package/dist/node_modules/lodash/_baseKeysIn.js +0 -2
- package/dist/node_modules/lodash/_baseLt.js +0 -2
- package/dist/node_modules/lodash/_baseMap.js +0 -2
- package/dist/node_modules/lodash/_baseMatches.js +0 -2
- package/dist/node_modules/lodash/_baseMatchesProperty.js +0 -2
- package/dist/node_modules/lodash/_baseOrderBy.js +0 -2
- package/dist/node_modules/lodash/_baseProperty.js +0 -2
- package/dist/node_modules/lodash/_basePropertyDeep.js +0 -2
- package/dist/node_modules/lodash/_baseRange.js +0 -2
- package/dist/node_modules/lodash/_baseRest.js +0 -2
- package/dist/node_modules/lodash/_baseSetToString.js +0 -2
- package/dist/node_modules/lodash/_baseSlice.js +0 -2
- package/dist/node_modules/lodash/_baseSome.js +0 -2
- package/dist/node_modules/lodash/_baseSortBy.js +0 -2
- package/dist/node_modules/lodash/_baseSum.js +0 -2
- package/dist/node_modules/lodash/_baseTimes.js +0 -2
- package/dist/node_modules/lodash/_baseToString.js +0 -2
- package/dist/node_modules/lodash/_baseTrim.js +0 -2
- package/dist/node_modules/lodash/_baseUnary.js +0 -2
- package/dist/node_modules/lodash/_baseUniq.js +0 -2
- package/dist/node_modules/lodash/_baseUnset.js +0 -2
- package/dist/node_modules/lodash/_cacheHas.js +0 -2
- package/dist/node_modules/lodash/_castPath.js +0 -2
- package/dist/node_modules/lodash/_castSlice.js +0 -2
- package/dist/node_modules/lodash/_cloneArrayBuffer.js +0 -2
- package/dist/node_modules/lodash/_cloneBuffer.js +0 -2
- package/dist/node_modules/lodash/_cloneDataView.js +0 -2
- package/dist/node_modules/lodash/_cloneRegExp.js +0 -2
- package/dist/node_modules/lodash/_cloneSymbol.js +0 -2
- package/dist/node_modules/lodash/_cloneTypedArray.js +0 -2
- package/dist/node_modules/lodash/_compareAscending.js +0 -2
- package/dist/node_modules/lodash/_compareMultiple.js +0 -2
- package/dist/node_modules/lodash/_copyArray.js +0 -2
- package/dist/node_modules/lodash/_copyObject.js +0 -2
- package/dist/node_modules/lodash/_copySymbols.js +0 -2
- package/dist/node_modules/lodash/_copySymbolsIn.js +0 -2
- package/dist/node_modules/lodash/_coreJsData.js +0 -2
- package/dist/node_modules/lodash/_createBaseEach.js +0 -2
- package/dist/node_modules/lodash/_createBaseFor.js +0 -2
- package/dist/node_modules/lodash/_createCaseFirst.js +0 -2
- package/dist/node_modules/lodash/_createFind.js +0 -2
- package/dist/node_modules/lodash/_createRange.js +0 -2
- package/dist/node_modules/lodash/_createSet.js +0 -2
- package/dist/node_modules/lodash/_customOmitClone.js +0 -2
- package/dist/node_modules/lodash/_defineProperty.js +0 -2
- package/dist/node_modules/lodash/_equalArrays.js +0 -2
- package/dist/node_modules/lodash/_equalByTag.js +0 -2
- package/dist/node_modules/lodash/_equalObjects.js +0 -2
- package/dist/node_modules/lodash/_flatRest.js +0 -2
- package/dist/node_modules/lodash/_freeGlobal.js +0 -2
- package/dist/node_modules/lodash/_getAllKeys.js +0 -2
- package/dist/node_modules/lodash/_getAllKeysIn.js +0 -2
- package/dist/node_modules/lodash/_getMapData.js +0 -2
- package/dist/node_modules/lodash/_getMatchData.js +0 -2
- package/dist/node_modules/lodash/_getNative.js +0 -2
- package/dist/node_modules/lodash/_getPrototype.js +0 -2
- package/dist/node_modules/lodash/_getRawTag.js +0 -2
- package/dist/node_modules/lodash/_getSymbols.js +0 -2
- package/dist/node_modules/lodash/_getSymbolsIn.js +0 -2
- package/dist/node_modules/lodash/_getTag.js +0 -2
- package/dist/node_modules/lodash/_getValue.js +0 -2
- package/dist/node_modules/lodash/_hasPath.js +0 -2
- package/dist/node_modules/lodash/_hasUnicode.js +0 -2
- package/dist/node_modules/lodash/_hashClear.js +0 -2
- package/dist/node_modules/lodash/_hashDelete.js +0 -2
- package/dist/node_modules/lodash/_hashGet.js +0 -2
- package/dist/node_modules/lodash/_hashHas.js +0 -2
- package/dist/node_modules/lodash/_hashSet.js +0 -2
- package/dist/node_modules/lodash/_initCloneArray.js +0 -2
- package/dist/node_modules/lodash/_initCloneByTag.js +0 -2
- package/dist/node_modules/lodash/_initCloneObject.js +0 -2
- package/dist/node_modules/lodash/_isFlattenable.js +0 -2
- package/dist/node_modules/lodash/_isIndex.js +0 -2
- package/dist/node_modules/lodash/_isIterateeCall.js +0 -2
- package/dist/node_modules/lodash/_isKey.js +0 -2
- package/dist/node_modules/lodash/_isKeyable.js +0 -2
- package/dist/node_modules/lodash/_isMasked.js +0 -2
- package/dist/node_modules/lodash/_isPrototype.js +0 -2
- package/dist/node_modules/lodash/_isStrictComparable.js +0 -2
- package/dist/node_modules/lodash/_listCacheClear.js +0 -2
- package/dist/node_modules/lodash/_listCacheDelete.js +0 -2
- package/dist/node_modules/lodash/_listCacheGet.js +0 -2
- package/dist/node_modules/lodash/_listCacheHas.js +0 -2
- package/dist/node_modules/lodash/_listCacheSet.js +0 -2
- package/dist/node_modules/lodash/_mapCacheClear.js +0 -2
- package/dist/node_modules/lodash/_mapCacheDelete.js +0 -2
- package/dist/node_modules/lodash/_mapCacheGet.js +0 -2
- package/dist/node_modules/lodash/_mapCacheHas.js +0 -2
- package/dist/node_modules/lodash/_mapCacheSet.js +0 -2
- package/dist/node_modules/lodash/_mapToArray.js +0 -2
- package/dist/node_modules/lodash/_matchesStrictComparable.js +0 -2
- package/dist/node_modules/lodash/_memoizeCapped.js +0 -2
- package/dist/node_modules/lodash/_nativeCreate.js +0 -2
- package/dist/node_modules/lodash/_nativeKeys.js +0 -2
- package/dist/node_modules/lodash/_nativeKeysIn.js +0 -2
- package/dist/node_modules/lodash/_nodeUtil.js +0 -2
- package/dist/node_modules/lodash/_objectToString.js +0 -2
- package/dist/node_modules/lodash/_overArg.js +0 -2
- package/dist/node_modules/lodash/_overRest.js +0 -2
- package/dist/node_modules/lodash/_parent.js +0 -2
- package/dist/node_modules/lodash/_root.js +0 -2
- package/dist/node_modules/lodash/_setCacheAdd.js +0 -2
- package/dist/node_modules/lodash/_setCacheHas.js +0 -2
- package/dist/node_modules/lodash/_setToArray.js +0 -2
- package/dist/node_modules/lodash/_setToString.js +0 -2
- package/dist/node_modules/lodash/_shortOut.js +0 -2
- package/dist/node_modules/lodash/_stackClear.js +0 -2
- package/dist/node_modules/lodash/_stackDelete.js +0 -2
- package/dist/node_modules/lodash/_stackGet.js +0 -2
- package/dist/node_modules/lodash/_stackHas.js +0 -2
- package/dist/node_modules/lodash/_stackSet.js +0 -2
- package/dist/node_modules/lodash/_strictIndexOf.js +0 -2
- package/dist/node_modules/lodash/_stringToArray.js +0 -2
- package/dist/node_modules/lodash/_stringToPath.js +0 -2
- package/dist/node_modules/lodash/_toKey.js +0 -2
- package/dist/node_modules/lodash/_toSource.js +0 -2
- package/dist/node_modules/lodash/_trimmedEndIndex.js +0 -2
- package/dist/node_modules/lodash/_unicodeToArray.js +0 -2
- package/dist/node_modules/lodash/constant.js +0 -2
- package/dist/node_modules/lodash/debounce.js +0 -2
- package/dist/node_modules/lodash/eq.js +0 -2
- package/dist/node_modules/lodash/every.js +0 -2
- package/dist/node_modules/lodash/find.js +0 -2
- package/dist/node_modules/lodash/findIndex.js +0 -2
- package/dist/node_modules/lodash/flatMap.js +0 -2
- package/dist/node_modules/lodash/flatten.js +0 -2
- package/dist/node_modules/lodash/get.js +0 -2
- package/dist/node_modules/lodash/hasIn.js +0 -2
- package/dist/node_modules/lodash/identity.js +0 -2
- package/dist/node_modules/lodash/isArguments.js +0 -2
- package/dist/node_modules/lodash/isArray.js +0 -2
- package/dist/node_modules/lodash/isArrayLike.js +0 -2
- package/dist/node_modules/lodash/isBoolean.js +0 -2
- package/dist/node_modules/lodash/isBuffer.js +0 -2
- package/dist/node_modules/lodash/isEqual.js +0 -2
- package/dist/node_modules/lodash/isFunction.js +0 -2
- package/dist/node_modules/lodash/isLength.js +0 -2
- package/dist/node_modules/lodash/isMap.js +0 -2
- package/dist/node_modules/lodash/isNaN.js +0 -2
- package/dist/node_modules/lodash/isNil.js +0 -2
- package/dist/node_modules/lodash/isNumber.js +0 -2
- package/dist/node_modules/lodash/isObject.js +0 -2
- package/dist/node_modules/lodash/isObjectLike.js +0 -2
- package/dist/node_modules/lodash/isPlainObject.js +0 -2
- package/dist/node_modules/lodash/isSet.js +0 -2
- package/dist/node_modules/lodash/isString.js +0 -2
- package/dist/node_modules/lodash/isSymbol.js +0 -2
- package/dist/node_modules/lodash/isTypedArray.js +0 -2
- package/dist/node_modules/lodash/keys.js +0 -2
- package/dist/node_modules/lodash/keysIn.js +0 -2
- package/dist/node_modules/lodash/last.js +0 -2
- package/dist/node_modules/lodash/map.js +0 -2
- package/dist/node_modules/lodash/mapValues.js +0 -2
- package/dist/node_modules/lodash/max.js +0 -2
- package/dist/node_modules/lodash/maxBy.js +0 -2
- package/dist/node_modules/lodash/memoize.js +0 -2
- package/dist/node_modules/lodash/min.js +0 -2
- package/dist/node_modules/lodash/noop.js +0 -2
- package/dist/node_modules/lodash/now.js +0 -2
- package/dist/node_modules/lodash/omit.js +0 -2
- package/dist/node_modules/lodash/property.js +0 -2
- package/dist/node_modules/lodash/range.js +0 -2
- package/dist/node_modules/lodash/some.js +0 -2
- package/dist/node_modules/lodash/sortBy.js +0 -2
- package/dist/node_modules/lodash/stubArray.js +0 -2
- package/dist/node_modules/lodash/stubFalse.js +0 -2
- package/dist/node_modules/lodash/sumBy.js +0 -2
- package/dist/node_modules/lodash/throttle.js +0 -2
- package/dist/node_modules/lodash/toFinite.js +0 -2
- package/dist/node_modules/lodash/toInteger.js +0 -2
- package/dist/node_modules/lodash/toNumber.js +0 -2
- package/dist/node_modules/lodash/toString.js +0 -2
- package/dist/node_modules/lodash/uniqBy.js +0 -2
- package/dist/node_modules/lodash/upperFirst.js +0 -2
- package/dist/node_modules/object-assign/index.js +0 -2
- package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js +0 -2
- package/dist/node_modules/prop-types/checkPropTypes.js +0 -2
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js +0 -2
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js +0 -2
- package/dist/node_modules/prop-types/index.js +0 -2
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js +0 -2
- package/dist/node_modules/prop-types/lib/has.js +0 -2
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js +0 -2
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.production.min.js +0 -2
- package/dist/node_modules/prop-types/node_modules/react-is/index.js +0 -2
- package/dist/node_modules/react-is/cjs/react-is.development.js +0 -2
- package/dist/node_modules/react-is/cjs/react-is.production.min.js +0 -2
- package/dist/node_modules/react-is/index.js +0 -2
- package/dist/node_modules/react-smooth/es6/Animate.js +0 -2
- package/dist/node_modules/react-smooth/es6/AnimateManager.js +0 -2
- package/dist/node_modules/react-smooth/es6/configUpdate.js +0 -2
- package/dist/node_modules/react-smooth/es6/easing.js +0 -2
- package/dist/node_modules/react-smooth/es6/index.js +0 -2
- package/dist/node_modules/react-smooth/es6/setRafTimeout.js +0 -2
- package/dist/node_modules/react-smooth/es6/util.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/Area.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/Bar.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/Brush.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/CartesianGrid.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/Line.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/XAxis.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/YAxis.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/getEquidistantTicks.js +0 -2
- package/dist/node_modules/recharts/es6/cartesian/getTicks.js +0 -2
- package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js +0 -2
- package/dist/node_modules/recharts/es6/chart/AreaChart.js +0 -2
- package/dist/node_modules/recharts/es6/chart/BarChart.js +0 -2
- package/dist/node_modules/recharts/es6/chart/LineChart.js +0 -2
- package/dist/node_modules/recharts/es6/chart/Sankey.js +0 -2
- package/dist/node_modules/recharts/es6/chart/Treemap.js +0 -2
- package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js +0 -2
- package/dist/node_modules/recharts/es6/component/Cell.js +0 -2
- package/dist/node_modules/recharts/es6/component/Cursor.js +0 -2
- package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js +0 -2
- package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js +0 -2
- package/dist/node_modules/recharts/es6/component/Label.js +0 -2
- package/dist/node_modules/recharts/es6/component/LabelList.js +0 -2
- package/dist/node_modules/recharts/es6/component/Legend.js +0 -2
- package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js +0 -2
- package/dist/node_modules/recharts/es6/component/Text.js +0 -2
- package/dist/node_modules/recharts/es6/component/Tooltip.js +0 -2
- package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js +0 -2
- package/dist/node_modules/recharts/es6/container/Layer.js +0 -2
- package/dist/node_modules/recharts/es6/container/Surface.js +0 -2
- package/dist/node_modules/recharts/es6/context/chartLayoutContext.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Cross.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Curve.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Dot.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Polygon.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Rectangle.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Sector.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Symbols.js +0 -2
- package/dist/node_modules/recharts/es6/shape/Trapezoid.js +0 -2
- package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/BarUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/CartesianUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/ChartUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/Constants.js +0 -2
- package/dist/node_modules/recharts/es6/util/CssPrefixUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/DOMUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/DataUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/DetectReferenceElementsDomain.js +0 -2
- package/dist/node_modules/recharts/es6/util/Events.js +0 -2
- package/dist/node_modules/recharts/es6/util/Global.js +0 -2
- package/dist/node_modules/recharts/es6/util/IfOverflowMatches.js +0 -2
- package/dist/node_modules/recharts/es6/util/LogUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/PolarUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/ReactUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js +0 -2
- package/dist/node_modules/recharts/es6/util/ShallowEqual.js +0 -2
- package/dist/node_modules/recharts/es6/util/TickUtils.js +0 -2
- package/dist/node_modules/recharts/es6/util/calculateViewBox.js +0 -2
- package/dist/node_modules/recharts/es6/util/cursor/getCursorPoints.js +0 -2
- package/dist/node_modules/recharts/es6/util/cursor/getCursorRectangle.js +0 -2
- package/dist/node_modules/recharts/es6/util/cursor/getRadialCursorPoints.js +0 -2
- package/dist/node_modules/recharts/es6/util/getEveryNthWithCondition.js +0 -2
- package/dist/node_modules/recharts/es6/util/getLegendProps.js +0 -2
- package/dist/node_modules/recharts/es6/util/isDomainSpecifiedByUser.js +0 -2
- package/dist/node_modules/recharts/es6/util/payload/getUniqPayload.js +0 -2
- package/dist/node_modules/recharts/es6/util/tooltip/translate.js +0 -2
- package/dist/node_modules/recharts/es6/util/types.js +0 -2
- package/dist/node_modules/recharts-scale/es6/getNiceTickValues.js +0 -2
- package/dist/node_modules/recharts-scale/es6/util/arithmetic.js +0 -2
- package/dist/node_modules/recharts-scale/es6/util/utils.js +0 -2
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +0 -2
- package/dist/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -2
- package/dist/node_modules/victory-vendor/es/d3-scale.js +0 -2
- package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js +0 -2
- package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js +0 -2
- package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js +0 -2
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js +0 -2
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js +0 -2
- package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/findElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js +0 -2
- package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js +0 -2
- package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js +0 -2
- package/dist/planmagnet/PlanMagnetRoot.js +0 -2
- package/dist/planmagnet/PlanMagnetRoutes.js +0 -2
- package/dist/planmagnet/activity/activityDescribe.js +0 -2
- package/dist/planmagnet/activity/relativeTime.js +0 -2
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +0 -2
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js +0 -2
- package/dist/planmagnet/automation/AutomationRuleFields.js +0 -2
- package/dist/planmagnet/automation/automationRuleTypes.js +0 -2
- package/dist/planmagnet/board/BoardViewBar.js +0 -2
- package/dist/planmagnet/board/BulkActions.js +0 -2
- package/dist/planmagnet/board/ProjectBoard.js +0 -2
- package/dist/planmagnet/board/boardViewConfig.js +0 -2
- package/dist/planmagnet/budgets/BudgetControls.js +0 -2
- package/dist/planmagnet/budgets/ExpenseControls.js +0 -2
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js +0 -2
- package/dist/planmagnet/budgets/budgetMath.js +0 -2
- package/dist/planmagnet/comments/CommentAttachmentUpload.js +0 -2
- package/dist/planmagnet/comments/CommentAttachments.js +0 -2
- package/dist/planmagnet/comments/CommentBody.js +0 -2
- package/dist/planmagnet/comments/CommentThread.js +0 -2
- package/dist/planmagnet/comments/MentionComposer.js +0 -2
- package/dist/planmagnet/comments/RoadmapComments.js +0 -2
- package/dist/planmagnet/comments/TargetComments.js +0 -2
- package/dist/planmagnet/comments/WorkItemActivity.js +0 -2
- package/dist/planmagnet/comments/WorkItemComments.js +0 -2
- package/dist/planmagnet/comments/commentAttachmentUploadClient.js +0 -2
- package/dist/planmagnet/comments/commentImageTokens.js +0 -2
- package/dist/planmagnet/comments/commentTokens.js +0 -2
- package/dist/planmagnet/comments/fileDisplay.js +0 -2
- package/dist/planmagnet/comments/useCommentFileUrl.js +0 -2
- package/dist/planmagnet/controls/AutomationRuleControls.js +0 -2
- package/dist/planmagnet/controls/CompetitorControls.js +0 -2
- package/dist/planmagnet/controls/ConfirmButton.js +0 -2
- package/dist/planmagnet/controls/CustomFieldControls.js +0 -2
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js +0 -2
- package/dist/planmagnet/controls/FeatureControls.js +0 -2
- package/dist/planmagnet/controls/FeatureTriage.js +0 -2
- package/dist/planmagnet/controls/FeedbackControls.js +0 -2
- package/dist/planmagnet/controls/LiveStatus.js +0 -2
- package/dist/planmagnet/controls/MilestoneControls.js +0 -2
- package/dist/planmagnet/controls/ObjectiveControls.js +0 -2
- package/dist/planmagnet/controls/Pickers.js +0 -2
- package/dist/planmagnet/controls/PortfolioControls.js +0 -2
- package/dist/planmagnet/controls/PrioritizationControls.js +0 -2
- package/dist/planmagnet/controls/ProgramControls.js +0 -2
- package/dist/planmagnet/controls/ProjectControls.js +0 -2
- package/dist/planmagnet/controls/QualityGateControls.js +0 -2
- package/dist/planmagnet/controls/ReleaseControls.js +0 -2
- package/dist/planmagnet/controls/RiskControls.js +0 -2
- package/dist/planmagnet/controls/SyncControls.js +0 -2
- package/dist/planmagnet/controls/TemplateControls.js +0 -2
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js +0 -2
- package/dist/planmagnet/controls/WorkItemControls.js +0 -2
- package/dist/planmagnet/create/CreateDialogs.js +0 -2
- package/dist/planmagnet/dashboards/DashboardUI.js +0 -2
- package/dist/planmagnet/dashboards/cards/DeliveryTimelineCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/ObjectivesProgressCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/PortfolioHealthCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/QualityMetricsCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/RoadmapHorizonCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/TaskCompletionCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/TeamCapacityCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/TeamOverviewCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/TeamWorkloadCard.js +0 -2
- package/dist/planmagnet/dashboards/cards/TimeLoggedCard.js +0 -2
- package/dist/planmagnet/dependency/DependencyGraph.js +0 -2
- package/dist/planmagnet/dependency/DependencyPanel.js +0 -2
- package/dist/planmagnet/dependency/GanttChart.js +0 -2
- package/dist/planmagnet/dependency/useProjectWorkItemsGraph.js +0 -2
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +0 -2
- package/dist/planmagnet/docs/DocDiffView.js +0 -2
- package/dist/planmagnet/docs/DocStatusBadge.js +0 -2
- package/dist/planmagnet/docs/DocSuggestionsPanel.js +0 -2
- package/dist/planmagnet/docs/DocVersionCompare.js +0 -2
- package/dist/planmagnet/export/ExportWorkItemsButton.js +0 -2
- package/dist/planmagnet/export/workItemsCsv.js +0 -2
- package/dist/planmagnet/forecast/DeliveryForecastCard.js +0 -2
- package/dist/planmagnet/forecast/ProjectOutlookCard.js +0 -2
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +0 -2
- package/dist/planmagnet/forecast/ResourceForecastCard.js +0 -2
- package/dist/planmagnet/forecast/riskFlags.js +0 -2
- package/dist/planmagnet/hooks/useCounts.js +0 -2
- package/dist/planmagnet/hooks/useEntityId.js +0 -2
- package/dist/planmagnet/hooks/useLiveRefresh.js +0 -2
- package/dist/planmagnet/hooks/usePresence.js +0 -2
- package/dist/planmagnet/hooks/useProjectWorkflow.js +0 -2
- package/dist/planmagnet/import/exportColumns.js +0 -2
- package/dist/planmagnet/integrations/routes.js +0 -2
- package/dist/planmagnet/integrations/syncTypes.js +0 -2
- package/dist/planmagnet/integrations/useSyncProviderCapabilities.js +0 -2
- package/dist/planmagnet/links/CodeLinksPanel.js +0 -2
- package/dist/planmagnet/links/IssueLinksPanel.js +0 -2
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.js +0 -2
- package/dist/planmagnet/meetings/MeetingsCard.js +0 -2
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.js +0 -2
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js +0 -2
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.js +0 -2
- package/dist/planmagnet/meetings/meetingActions.js +0 -2
- package/dist/planmagnet/meetings/meetingGraphql.js +0 -2
- package/dist/planmagnet/meetings/meetingModel.js +0 -2
- package/dist/planmagnet/milestones/MilestoneControls.js +0 -2
- package/dist/planmagnet/pages/ActivityActivityPagePage.js +0 -2
- package/dist/planmagnet/pages/AiActivityPagePage.js +0 -2
- package/dist/planmagnet/pages/AiPlanPagePage.js +0 -2
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +0 -2
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +0 -2
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +0 -2
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +0 -2
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +0 -2
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +0 -2
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js +0 -2
- package/dist/planmagnet/pages/DashboardsExecutivePagePage.js +0 -2
- package/dist/planmagnet/pages/DashboardsLeadershipPagePage.js +0 -2
- package/dist/planmagnet/pages/DashboardsProjectManagerPagePage.js +0 -2
- package/dist/planmagnet/pages/DashboardsTeamUtilizationPagePage.js +0 -2
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/DocsDocsPagePage.js +0 -2
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js +0 -2
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js +0 -2
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js +0 -2
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +0 -2
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +0 -2
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.js +0 -2
- package/dist/planmagnet/pages/NotFoundPage.js +0 -2
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js +0 -2
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js +0 -2
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsCustomerSatisfactionPagePage.js +93 -82
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsProductFeatureDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsProductHierarchyPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsProductLinesPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsProductsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js +0 -2
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js +0 -2
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsGanttPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsQualityGatesPagePage.js +0 -2
- package/dist/planmagnet/pages/ProjectsWorkflowPagePage.js +0 -2
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.js +0 -2
- package/dist/planmagnet/pages/ReportsEditReportPagePage.js +0 -2
- package/dist/planmagnet/pages/ReportsReportPagePage.js +0 -2
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +0 -2
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js +0 -2
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksImportPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksMyWorkPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksTasksPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamCreateTeamPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamInviteMemberPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamTeamEditPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamTeamPagePage.js +0 -2
- package/dist/planmagnet/pages/TeamTeamsListPagePage.js +0 -2
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js +0 -2
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js +0 -2
- package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.js +0 -2
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +0 -2
- package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +0 -2
- package/dist/planmagnet/pages/analytics/MetricsCard.js +0 -2
- package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +0 -2
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +0 -2
- package/dist/planmagnet/pages/analytics/StatusFlowCard.js +0 -2
- package/dist/planmagnet/pages/analytics/ThroughputCard.js +0 -2
- package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +0 -2
- package/dist/planmagnet/pages/analytics/analyticsRange.js +0 -2
- package/dist/planmagnet/people/People.js +0 -2
- package/dist/planmagnet/presence/PresenceAvatars.js +0 -2
- package/dist/planmagnet/product/FeatureLinkPanels.js +0 -2
- package/dist/planmagnet/product/ProductControls.js +0 -2
- package/dist/planmagnet/product/ProductFeatureControls.js +0 -2
- package/dist/planmagnet/product/ProductFeatureLinkCard.js +0 -2
- package/dist/planmagnet/product/ProductLineControls.js +0 -2
- package/dist/planmagnet/product/ProductTeamsPanel.js +0 -2
- package/dist/planmagnet/product/WorkItemProductFeatureChip.js +0 -2
- package/dist/planmagnet/product/hierarchy.js +0 -2
- package/dist/planmagnet/product/hierarchyOperations.js +0 -2
- package/dist/planmagnet/product/refusal.js +0 -2
- package/dist/planmagnet/product/routes.js +0 -2
- package/dist/planmagnet/providers/PlanMagnetProvider.js +0 -2
- package/dist/planmagnet/releases/ReleaseChecklistCard.js +0 -2
- package/dist/planmagnet/releases/ReleaseGatesCard.js +0 -2
- package/dist/planmagnet/releases/ReleaseNotesCard.js +0 -2
- package/dist/planmagnet/releases/ReleaseReadinessCard.js +0 -2
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.js +0 -2
- package/dist/planmagnet/releases/useReleaseOptions.js +0 -2
- package/dist/planmagnet/reports/ExportMenu.js +0 -2
- package/dist/planmagnet/reports/PrintReportView.js +0 -2
- package/dist/planmagnet/reports/ReportBuilderCanvas.js +0 -2
- package/dist/planmagnet/reports/ReportBuilderPage.js +0 -2
- package/dist/planmagnet/reports/ReportRunHistory.js +0 -2
- package/dist/planmagnet/reports/ReportWidgetRenderer.js +0 -2
- package/dist/planmagnet/reports/SchedulesPanel.js +0 -2
- package/dist/planmagnet/reports/ShareDialog.js +0 -2
- package/dist/planmagnet/reports/SharedReportPage.js +0 -2
- package/dist/planmagnet/reports/WidgetEditorDialog.js +0 -2
- package/dist/planmagnet/reports/reportExportPptx.js +0 -2
- package/dist/planmagnet/reports/reportExportXlsx.js +0 -2
- package/dist/planmagnet/reports/reportGraphql.js +0 -2
- package/dist/planmagnet/reports/reportModel.js +0 -2
- package/dist/planmagnet/reports/sharedReportRoute.js +0 -2
- package/dist/planmagnet/roadmaps/FeatureInitiativeCard.js +0 -2
- package/dist/planmagnet/roadmaps/RoadmapControls.js +0 -2
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +0 -2
- package/dist/planmagnet/roadmaps/RoadmapPresentation.js +0 -2
- package/dist/planmagnet/roadmaps/RoadmapReviewPanel.js +0 -2
- package/dist/planmagnet/roadmaps/RoadmapVersionsPanel.js +0 -2
- package/dist/planmagnet/roadmaps/planningFocus.js +0 -2
- package/dist/planmagnet/satisfaction/DeliverySatisfactionSection.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionFigures.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionImportDialog.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionLinkFields.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionReleaseSelect.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionResponseDialog.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionResponsesTable.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionSummaryCard.js +0 -2
- package/dist/planmagnet/satisfaction/SatisfactionWindowPicker.js +0 -2
- package/dist/planmagnet/satisfaction/satisfaction.d.ts +2 -1
- package/dist/planmagnet/satisfaction/satisfaction.js +2 -4
- package/dist/planmagnet/satisfaction/satisfactionCsv.js +0 -2
- package/dist/planmagnet/satisfaction/satisfactionForm.js +0 -2
- package/dist/planmagnet/satisfaction/satisfactionOperations.js +0 -2
- package/dist/planmagnet/satisfaction/useSatisfactionAccess.js +0 -2
- package/dist/planmagnet/skills/RequiredSkillsEditor.js +0 -2
- package/dist/planmagnet/skills/SkillChips.js +0 -2
- package/dist/planmagnet/skills/SkillCoverageCard.js +0 -2
- package/dist/planmagnet/skills/WorkItemRequiredSkills.js +0 -2
- package/dist/planmagnet/skills/skillOperations.js +0 -2
- package/dist/planmagnet/skills/skillTags.js +0 -2
- package/dist/planmagnet/skills/useRequiredSkillsDraft.js +0 -2
- package/dist/planmagnet/sprints/SprintControls.js +0 -2
- package/dist/planmagnet/sprints/SprintDates.js +0 -2
- package/dist/planmagnet/store/planmagnetStore.js +0 -2
- package/dist/planmagnet/team/PendingInvitations.js +0 -2
- package/dist/planmagnet/team/TeamControls.js +0 -2
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js +0 -2
- package/dist/planmagnet/team/invitationEmail.js +0 -2
- package/dist/planmagnet/time/TaskTimePanel.js +0 -2
- package/dist/planmagnet/time/TimeEntryControls.js +0 -2
- package/dist/planmagnet/time/TimesheetControls.js +0 -2
- package/dist/planmagnet/time/timeShared.js +0 -2
- package/dist/planmagnet/utils/cn.js +0 -2
- package/dist/planmagnet/utils/email.js +0 -2
- package/dist/planmagnet/utils/formValidation.js +0 -2
- package/dist/planmagnet/utils/graphqlErrors.js +0 -2
- package/dist/planmagnet/utils/lineDiff.js +0 -2
- package/dist/planmagnet/utils/mutationResult.js +0 -2
- package/dist/planmagnet/utils/navigation.js +0 -2
- package/dist/planmagnet/utils/qualityGateCriteria.js +0 -2
- package/dist/planmagnet/utils/rowNavigation.js +0 -2
- package/dist/planmagnet/utils/statusColor.js +0 -2
- package/dist/planmagnet/utils/urlParam.js +0 -2
- package/dist/planmagnet/webhooks/webhookTypes.js +0 -2
- package/dist/shared/hooks/useTr.js +0 -2
- package/dist/shared/utils/i18n.js +0 -2
- package/package.json +2 -1
- package/dist/_virtual/__vite-browser-external.js.map +0 -1
- package/dist/components/Button.d.ts.map +0 -1
- package/dist/components/Button.stories.d.ts.map +0 -1
- package/dist/components/MarkdownEditor.d.ts.map +0 -1
- package/dist/components/MarkdownEditor.js.map +0 -1
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
- package/dist/node_modules/@apollo/client/errors/ServerError.js.map +0 -1
- package/dist/node_modules/@apollo/client/errors/utils.js.map +0 -1
- package/dist/node_modules/clsx/dist/clsx.js.map +0 -1
- package/dist/node_modules/d3-array/src/ascending.js.map +0 -1
- package/dist/node_modules/d3-array/src/bisect.js.map +0 -1
- package/dist/node_modules/d3-array/src/bisector.js.map +0 -1
- package/dist/node_modules/d3-array/src/descending.js.map +0 -1
- package/dist/node_modules/d3-array/src/max.js.map +0 -1
- package/dist/node_modules/d3-array/src/min.js.map +0 -1
- package/dist/node_modules/d3-array/src/number.js.map +0 -1
- package/dist/node_modules/d3-array/src/quantile.js.map +0 -1
- package/dist/node_modules/d3-array/src/quickselect.js.map +0 -1
- package/dist/node_modules/d3-array/src/range.js.map +0 -1
- package/dist/node_modules/d3-array/src/sort.js.map +0 -1
- package/dist/node_modules/d3-array/src/ticks.js.map +0 -1
- package/dist/node_modules/d3-color/src/color.js.map +0 -1
- package/dist/node_modules/d3-color/src/define.js.map +0 -1
- package/dist/node_modules/d3-format/src/defaultLocale.js.map +0 -1
- package/dist/node_modules/d3-format/src/exponent.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatDecimal.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatGroup.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatNumerals.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatPrefixAuto.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatRounded.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatSpecifier.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatTrim.js.map +0 -1
- package/dist/node_modules/d3-format/src/formatTypes.js.map +0 -1
- package/dist/node_modules/d3-format/src/identity.js.map +0 -1
- package/dist/node_modules/d3-format/src/locale.js.map +0 -1
- package/dist/node_modules/d3-format/src/precisionFixed.js.map +0 -1
- package/dist/node_modules/d3-format/src/precisionPrefix.js.map +0 -1
- package/dist/node_modules/d3-format/src/precisionRound.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/array.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/basis.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/basisClosed.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/color.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/constant.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/date.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/number.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/numberArray.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/object.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/piecewise.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/rgb.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/round.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/string.js.map +0 -1
- package/dist/node_modules/d3-interpolate/src/value.js.map +0 -1
- package/dist/node_modules/d3-path/src/path.js.map +0 -1
- package/dist/node_modules/d3-scale/src/band.js.map +0 -1
- package/dist/node_modules/d3-scale/src/constant.js.map +0 -1
- package/dist/node_modules/d3-scale/src/continuous.js.map +0 -1
- package/dist/node_modules/d3-scale/src/diverging.js.map +0 -1
- package/dist/node_modules/d3-scale/src/identity.js.map +0 -1
- package/dist/node_modules/d3-scale/src/init.js.map +0 -1
- package/dist/node_modules/d3-scale/src/linear.js.map +0 -1
- package/dist/node_modules/d3-scale/src/log.js.map +0 -1
- package/dist/node_modules/d3-scale/src/nice.js.map +0 -1
- package/dist/node_modules/d3-scale/src/number.js.map +0 -1
- package/dist/node_modules/d3-scale/src/ordinal.js.map +0 -1
- package/dist/node_modules/d3-scale/src/pow.js.map +0 -1
- package/dist/node_modules/d3-scale/src/quantile.js.map +0 -1
- package/dist/node_modules/d3-scale/src/quantize.js.map +0 -1
- package/dist/node_modules/d3-scale/src/radial.js.map +0 -1
- package/dist/node_modules/d3-scale/src/sequential.js.map +0 -1
- package/dist/node_modules/d3-scale/src/sequentialQuantile.js.map +0 -1
- package/dist/node_modules/d3-scale/src/symlog.js.map +0 -1
- package/dist/node_modules/d3-scale/src/threshold.js.map +0 -1
- package/dist/node_modules/d3-scale/src/tickFormat.js.map +0 -1
- package/dist/node_modules/d3-scale/src/time.js.map +0 -1
- package/dist/node_modules/d3-scale/src/utcTime.js.map +0 -1
- package/dist/node_modules/d3-shape/src/area.js.map +0 -1
- package/dist/node_modules/d3-shape/src/array.js.map +0 -1
- package/dist/node_modules/d3-shape/src/constant.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/basis.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/basisClosed.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/basisOpen.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/bump.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/linear.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/linearClosed.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/monotone.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/natural.js.map +0 -1
- package/dist/node_modules/d3-shape/src/curve/step.js.map +0 -1
- package/dist/node_modules/d3-shape/src/line.js.map +0 -1
- package/dist/node_modules/d3-shape/src/math.js.map +0 -1
- package/dist/node_modules/d3-shape/src/noop.js.map +0 -1
- package/dist/node_modules/d3-shape/src/offset/expand.js.map +0 -1
- package/dist/node_modules/d3-shape/src/offset/none.js.map +0 -1
- package/dist/node_modules/d3-shape/src/offset/silhouette.js.map +0 -1
- package/dist/node_modules/d3-shape/src/offset/wiggle.js.map +0 -1
- package/dist/node_modules/d3-shape/src/order/none.js.map +0 -1
- package/dist/node_modules/d3-shape/src/path.js.map +0 -1
- package/dist/node_modules/d3-shape/src/point.js.map +0 -1
- package/dist/node_modules/d3-shape/src/stack.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/circle.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/cross.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/diamond.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/square.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/star.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/triangle.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol/wye.js.map +0 -1
- package/dist/node_modules/d3-shape/src/symbol.js.map +0 -1
- package/dist/node_modules/d3-time/src/day.js.map +0 -1
- package/dist/node_modules/d3-time/src/duration.js.map +0 -1
- package/dist/node_modules/d3-time/src/hour.js.map +0 -1
- package/dist/node_modules/d3-time/src/interval.js.map +0 -1
- package/dist/node_modules/d3-time/src/millisecond.js.map +0 -1
- package/dist/node_modules/d3-time/src/minute.js.map +0 -1
- package/dist/node_modules/d3-time/src/month.js.map +0 -1
- package/dist/node_modules/d3-time/src/second.js.map +0 -1
- package/dist/node_modules/d3-time/src/ticks.js.map +0 -1
- package/dist/node_modules/d3-time/src/week.js.map +0 -1
- package/dist/node_modules/d3-time/src/year.js.map +0 -1
- package/dist/node_modules/d3-time-format/src/defaultLocale.js.map +0 -1
- package/dist/node_modules/d3-time-format/src/locale.js.map +0 -1
- package/dist/node_modules/decimal.js-light/decimal.js.map +0 -1
- package/dist/node_modules/eventemitter3/index.js.map +0 -1
- package/dist/node_modules/fast-equals/dist/es/index.js.map +0 -1
- package/dist/node_modules/fflate/esm/browser.js.map +0 -1
- package/dist/node_modules/internmap/src/index.js.map +0 -1
- package/dist/node_modules/jszip/dist/jszip.min.js.map +0 -1
- package/dist/node_modules/lodash/_DataView.js.map +0 -1
- package/dist/node_modules/lodash/_Hash.js.map +0 -1
- package/dist/node_modules/lodash/_ListCache.js.map +0 -1
- package/dist/node_modules/lodash/_Map.js.map +0 -1
- package/dist/node_modules/lodash/_MapCache.js.map +0 -1
- package/dist/node_modules/lodash/_Promise.js.map +0 -1
- package/dist/node_modules/lodash/_Set.js.map +0 -1
- package/dist/node_modules/lodash/_SetCache.js.map +0 -1
- package/dist/node_modules/lodash/_Stack.js.map +0 -1
- package/dist/node_modules/lodash/_Symbol.js.map +0 -1
- package/dist/node_modules/lodash/_Uint8Array.js.map +0 -1
- package/dist/node_modules/lodash/_WeakMap.js.map +0 -1
- package/dist/node_modules/lodash/_apply.js.map +0 -1
- package/dist/node_modules/lodash/_arrayEach.js.map +0 -1
- package/dist/node_modules/lodash/_arrayEvery.js.map +0 -1
- package/dist/node_modules/lodash/_arrayFilter.js.map +0 -1
- package/dist/node_modules/lodash/_arrayIncludes.js.map +0 -1
- package/dist/node_modules/lodash/_arrayIncludesWith.js.map +0 -1
- package/dist/node_modules/lodash/_arrayLikeKeys.js.map +0 -1
- package/dist/node_modules/lodash/_arrayMap.js.map +0 -1
- package/dist/node_modules/lodash/_arrayPush.js.map +0 -1
- package/dist/node_modules/lodash/_arraySome.js.map +0 -1
- package/dist/node_modules/lodash/_asciiToArray.js.map +0 -1
- package/dist/node_modules/lodash/_assignValue.js.map +0 -1
- package/dist/node_modules/lodash/_assocIndexOf.js.map +0 -1
- package/dist/node_modules/lodash/_baseAssign.js.map +0 -1
- package/dist/node_modules/lodash/_baseAssignIn.js.map +0 -1
- package/dist/node_modules/lodash/_baseAssignValue.js.map +0 -1
- package/dist/node_modules/lodash/_baseClone.js.map +0 -1
- package/dist/node_modules/lodash/_baseCreate.js.map +0 -1
- package/dist/node_modules/lodash/_baseEach.js.map +0 -1
- package/dist/node_modules/lodash/_baseEvery.js.map +0 -1
- package/dist/node_modules/lodash/_baseExtremum.js.map +0 -1
- package/dist/node_modules/lodash/_baseFindIndex.js.map +0 -1
- package/dist/node_modules/lodash/_baseFlatten.js.map +0 -1
- package/dist/node_modules/lodash/_baseFor.js.map +0 -1
- package/dist/node_modules/lodash/_baseForOwn.js.map +0 -1
- package/dist/node_modules/lodash/_baseGet.js.map +0 -1
- package/dist/node_modules/lodash/_baseGetAllKeys.js.map +0 -1
- package/dist/node_modules/lodash/_baseGetTag.js.map +0 -1
- package/dist/node_modules/lodash/_baseGt.js.map +0 -1
- package/dist/node_modules/lodash/_baseHasIn.js.map +0 -1
- package/dist/node_modules/lodash/_baseIndexOf.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsArguments.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsEqual.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsEqualDeep.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsMap.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsMatch.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsNaN.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsNative.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsSet.js.map +0 -1
- package/dist/node_modules/lodash/_baseIsTypedArray.js.map +0 -1
- package/dist/node_modules/lodash/_baseIteratee.js.map +0 -1
- package/dist/node_modules/lodash/_baseKeys.js.map +0 -1
- package/dist/node_modules/lodash/_baseKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_baseLt.js.map +0 -1
- package/dist/node_modules/lodash/_baseMap.js.map +0 -1
- package/dist/node_modules/lodash/_baseMatches.js.map +0 -1
- package/dist/node_modules/lodash/_baseMatchesProperty.js.map +0 -1
- package/dist/node_modules/lodash/_baseOrderBy.js.map +0 -1
- package/dist/node_modules/lodash/_baseProperty.js.map +0 -1
- package/dist/node_modules/lodash/_basePropertyDeep.js.map +0 -1
- package/dist/node_modules/lodash/_baseRange.js.map +0 -1
- package/dist/node_modules/lodash/_baseRest.js.map +0 -1
- package/dist/node_modules/lodash/_baseSetToString.js.map +0 -1
- package/dist/node_modules/lodash/_baseSlice.js.map +0 -1
- package/dist/node_modules/lodash/_baseSome.js.map +0 -1
- package/dist/node_modules/lodash/_baseSortBy.js.map +0 -1
- package/dist/node_modules/lodash/_baseSum.js.map +0 -1
- package/dist/node_modules/lodash/_baseTimes.js.map +0 -1
- package/dist/node_modules/lodash/_baseToString.js.map +0 -1
- package/dist/node_modules/lodash/_baseTrim.js.map +0 -1
- package/dist/node_modules/lodash/_baseUnary.js.map +0 -1
- package/dist/node_modules/lodash/_baseUniq.js.map +0 -1
- package/dist/node_modules/lodash/_baseUnset.js.map +0 -1
- package/dist/node_modules/lodash/_cacheHas.js.map +0 -1
- package/dist/node_modules/lodash/_castPath.js.map +0 -1
- package/dist/node_modules/lodash/_castSlice.js.map +0 -1
- package/dist/node_modules/lodash/_cloneArrayBuffer.js.map +0 -1
- package/dist/node_modules/lodash/_cloneBuffer.js.map +0 -1
- package/dist/node_modules/lodash/_cloneDataView.js.map +0 -1
- package/dist/node_modules/lodash/_cloneRegExp.js.map +0 -1
- package/dist/node_modules/lodash/_cloneSymbol.js.map +0 -1
- package/dist/node_modules/lodash/_cloneTypedArray.js.map +0 -1
- package/dist/node_modules/lodash/_compareAscending.js.map +0 -1
- package/dist/node_modules/lodash/_compareMultiple.js.map +0 -1
- package/dist/node_modules/lodash/_copyArray.js.map +0 -1
- package/dist/node_modules/lodash/_copyObject.js.map +0 -1
- package/dist/node_modules/lodash/_copySymbols.js.map +0 -1
- package/dist/node_modules/lodash/_copySymbolsIn.js.map +0 -1
- package/dist/node_modules/lodash/_coreJsData.js.map +0 -1
- package/dist/node_modules/lodash/_createBaseEach.js.map +0 -1
- package/dist/node_modules/lodash/_createBaseFor.js.map +0 -1
- package/dist/node_modules/lodash/_createCaseFirst.js.map +0 -1
- package/dist/node_modules/lodash/_createFind.js.map +0 -1
- package/dist/node_modules/lodash/_createRange.js.map +0 -1
- package/dist/node_modules/lodash/_createSet.js.map +0 -1
- package/dist/node_modules/lodash/_customOmitClone.js.map +0 -1
- package/dist/node_modules/lodash/_defineProperty.js.map +0 -1
- package/dist/node_modules/lodash/_equalArrays.js.map +0 -1
- package/dist/node_modules/lodash/_equalByTag.js.map +0 -1
- package/dist/node_modules/lodash/_equalObjects.js.map +0 -1
- package/dist/node_modules/lodash/_flatRest.js.map +0 -1
- package/dist/node_modules/lodash/_freeGlobal.js.map +0 -1
- package/dist/node_modules/lodash/_getAllKeys.js.map +0 -1
- package/dist/node_modules/lodash/_getAllKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_getMapData.js.map +0 -1
- package/dist/node_modules/lodash/_getMatchData.js.map +0 -1
- package/dist/node_modules/lodash/_getNative.js.map +0 -1
- package/dist/node_modules/lodash/_getPrototype.js.map +0 -1
- package/dist/node_modules/lodash/_getRawTag.js.map +0 -1
- package/dist/node_modules/lodash/_getSymbols.js.map +0 -1
- package/dist/node_modules/lodash/_getSymbolsIn.js.map +0 -1
- package/dist/node_modules/lodash/_getTag.js.map +0 -1
- package/dist/node_modules/lodash/_getValue.js.map +0 -1
- package/dist/node_modules/lodash/_hasPath.js.map +0 -1
- package/dist/node_modules/lodash/_hasUnicode.js.map +0 -1
- package/dist/node_modules/lodash/_hashClear.js.map +0 -1
- package/dist/node_modules/lodash/_hashDelete.js.map +0 -1
- package/dist/node_modules/lodash/_hashGet.js.map +0 -1
- package/dist/node_modules/lodash/_hashHas.js.map +0 -1
- package/dist/node_modules/lodash/_hashSet.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneArray.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneByTag.js.map +0 -1
- package/dist/node_modules/lodash/_initCloneObject.js.map +0 -1
- package/dist/node_modules/lodash/_isFlattenable.js.map +0 -1
- package/dist/node_modules/lodash/_isIndex.js.map +0 -1
- package/dist/node_modules/lodash/_isIterateeCall.js.map +0 -1
- package/dist/node_modules/lodash/_isKey.js.map +0 -1
- package/dist/node_modules/lodash/_isKeyable.js.map +0 -1
- package/dist/node_modules/lodash/_isMasked.js.map +0 -1
- package/dist/node_modules/lodash/_isPrototype.js.map +0 -1
- package/dist/node_modules/lodash/_isStrictComparable.js.map +0 -1
- package/dist/node_modules/lodash/_listCacheClear.js.map +0 -1
- package/dist/node_modules/lodash/_listCacheDelete.js.map +0 -1
- package/dist/node_modules/lodash/_listCacheGet.js.map +0 -1
- package/dist/node_modules/lodash/_listCacheHas.js.map +0 -1
- package/dist/node_modules/lodash/_listCacheSet.js.map +0 -1
- package/dist/node_modules/lodash/_mapCacheClear.js.map +0 -1
- package/dist/node_modules/lodash/_mapCacheDelete.js.map +0 -1
- package/dist/node_modules/lodash/_mapCacheGet.js.map +0 -1
- package/dist/node_modules/lodash/_mapCacheHas.js.map +0 -1
- package/dist/node_modules/lodash/_mapCacheSet.js.map +0 -1
- package/dist/node_modules/lodash/_mapToArray.js.map +0 -1
- package/dist/node_modules/lodash/_matchesStrictComparable.js.map +0 -1
- package/dist/node_modules/lodash/_memoizeCapped.js.map +0 -1
- package/dist/node_modules/lodash/_nativeCreate.js.map +0 -1
- package/dist/node_modules/lodash/_nativeKeys.js.map +0 -1
- package/dist/node_modules/lodash/_nativeKeysIn.js.map +0 -1
- package/dist/node_modules/lodash/_nodeUtil.js.map +0 -1
- package/dist/node_modules/lodash/_objectToString.js.map +0 -1
- package/dist/node_modules/lodash/_overArg.js.map +0 -1
- package/dist/node_modules/lodash/_overRest.js.map +0 -1
- package/dist/node_modules/lodash/_parent.js.map +0 -1
- package/dist/node_modules/lodash/_root.js.map +0 -1
- package/dist/node_modules/lodash/_setCacheAdd.js.map +0 -1
- package/dist/node_modules/lodash/_setCacheHas.js.map +0 -1
- package/dist/node_modules/lodash/_setToArray.js.map +0 -1
- package/dist/node_modules/lodash/_setToString.js.map +0 -1
- package/dist/node_modules/lodash/_shortOut.js.map +0 -1
- package/dist/node_modules/lodash/_stackClear.js.map +0 -1
- package/dist/node_modules/lodash/_stackDelete.js.map +0 -1
- package/dist/node_modules/lodash/_stackGet.js.map +0 -1
- package/dist/node_modules/lodash/_stackHas.js.map +0 -1
- package/dist/node_modules/lodash/_stackSet.js.map +0 -1
- package/dist/node_modules/lodash/_strictIndexOf.js.map +0 -1
- package/dist/node_modules/lodash/_stringToArray.js.map +0 -1
- package/dist/node_modules/lodash/_stringToPath.js.map +0 -1
- package/dist/node_modules/lodash/_toKey.js.map +0 -1
- package/dist/node_modules/lodash/_toSource.js.map +0 -1
- package/dist/node_modules/lodash/_trimmedEndIndex.js.map +0 -1
- package/dist/node_modules/lodash/_unicodeToArray.js.map +0 -1
- package/dist/node_modules/lodash/constant.js.map +0 -1
- package/dist/node_modules/lodash/debounce.js.map +0 -1
- package/dist/node_modules/lodash/eq.js.map +0 -1
- package/dist/node_modules/lodash/every.js.map +0 -1
- package/dist/node_modules/lodash/find.js.map +0 -1
- package/dist/node_modules/lodash/findIndex.js.map +0 -1
- package/dist/node_modules/lodash/flatMap.js.map +0 -1
- package/dist/node_modules/lodash/flatten.js.map +0 -1
- package/dist/node_modules/lodash/get.js.map +0 -1
- package/dist/node_modules/lodash/hasIn.js.map +0 -1
- package/dist/node_modules/lodash/identity.js.map +0 -1
- package/dist/node_modules/lodash/isArguments.js.map +0 -1
- package/dist/node_modules/lodash/isArray.js.map +0 -1
- package/dist/node_modules/lodash/isArrayLike.js.map +0 -1
- package/dist/node_modules/lodash/isBoolean.js.map +0 -1
- package/dist/node_modules/lodash/isBuffer.js.map +0 -1
- package/dist/node_modules/lodash/isEqual.js.map +0 -1
- package/dist/node_modules/lodash/isFunction.js.map +0 -1
- package/dist/node_modules/lodash/isLength.js.map +0 -1
- package/dist/node_modules/lodash/isMap.js.map +0 -1
- package/dist/node_modules/lodash/isNaN.js.map +0 -1
- package/dist/node_modules/lodash/isNil.js.map +0 -1
- package/dist/node_modules/lodash/isNumber.js.map +0 -1
- package/dist/node_modules/lodash/isObject.js.map +0 -1
- package/dist/node_modules/lodash/isObjectLike.js.map +0 -1
- package/dist/node_modules/lodash/isPlainObject.js.map +0 -1
- package/dist/node_modules/lodash/isSet.js.map +0 -1
- package/dist/node_modules/lodash/isString.js.map +0 -1
- package/dist/node_modules/lodash/isSymbol.js.map +0 -1
- package/dist/node_modules/lodash/isTypedArray.js.map +0 -1
- package/dist/node_modules/lodash/keys.js.map +0 -1
- package/dist/node_modules/lodash/keysIn.js.map +0 -1
- package/dist/node_modules/lodash/last.js.map +0 -1
- package/dist/node_modules/lodash/map.js.map +0 -1
- package/dist/node_modules/lodash/mapValues.js.map +0 -1
- package/dist/node_modules/lodash/max.js.map +0 -1
- package/dist/node_modules/lodash/maxBy.js.map +0 -1
- package/dist/node_modules/lodash/memoize.js.map +0 -1
- package/dist/node_modules/lodash/min.js.map +0 -1
- package/dist/node_modules/lodash/noop.js.map +0 -1
- package/dist/node_modules/lodash/now.js.map +0 -1
- package/dist/node_modules/lodash/omit.js.map +0 -1
- package/dist/node_modules/lodash/property.js.map +0 -1
- package/dist/node_modules/lodash/range.js.map +0 -1
- package/dist/node_modules/lodash/some.js.map +0 -1
- package/dist/node_modules/lodash/sortBy.js.map +0 -1
- package/dist/node_modules/lodash/stubArray.js.map +0 -1
- package/dist/node_modules/lodash/stubFalse.js.map +0 -1
- package/dist/node_modules/lodash/sumBy.js.map +0 -1
- package/dist/node_modules/lodash/throttle.js.map +0 -1
- package/dist/node_modules/lodash/toFinite.js.map +0 -1
- package/dist/node_modules/lodash/toInteger.js.map +0 -1
- package/dist/node_modules/lodash/toNumber.js.map +0 -1
- package/dist/node_modules/lodash/toString.js.map +0 -1
- package/dist/node_modules/lodash/uniqBy.js.map +0 -1
- package/dist/node_modules/lodash/upperFirst.js.map +0 -1
- package/dist/node_modules/object-assign/index.js.map +0 -1
- package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js.map +0 -1
- package/dist/node_modules/prop-types/checkPropTypes.js.map +0 -1
- package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +0 -1
- package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +0 -1
- package/dist/node_modules/prop-types/index.js.map +0 -1
- package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +0 -1
- package/dist/node_modules/prop-types/lib/has.js.map +0 -1
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js.map +0 -1
- package/dist/node_modules/prop-types/node_modules/react-is/cjs/react-is.production.min.js.map +0 -1
- package/dist/node_modules/prop-types/node_modules/react-is/index.js.map +0 -1
- package/dist/node_modules/react-is/cjs/react-is.development.js.map +0 -1
- package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +0 -1
- package/dist/node_modules/react-is/index.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/Animate.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/AnimateManager.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/configUpdate.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/easing.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/index.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/setRafTimeout.js.map +0 -1
- package/dist/node_modules/react-smooth/es6/util.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/Area.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/Bar.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/Brush.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/CartesianAxis.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/CartesianGrid.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/ErrorBar.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/Line.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceArea.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceDot.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/ReferenceLine.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/XAxis.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/YAxis.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/getEquidistantTicks.js.map +0 -1
- package/dist/node_modules/recharts/es6/cartesian/getTicks.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/AccessibilityManager.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/AreaChart.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/BarChart.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/LineChart.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/Sankey.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/Treemap.js.map +0 -1
- package/dist/node_modules/recharts/es6/chart/generateCategoricalChart.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Cell.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Cursor.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/DefaultLegendContent.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/DefaultTooltipContent.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Label.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/LabelList.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Legend.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/ResponsiveContainer.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Text.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/Tooltip.js.map +0 -1
- package/dist/node_modules/recharts/es6/component/TooltipBoundingBox.js.map +0 -1
- package/dist/node_modules/recharts/es6/container/Layer.js.map +0 -1
- package/dist/node_modules/recharts/es6/container/Surface.js.map +0 -1
- package/dist/node_modules/recharts/es6/context/chartLayoutContext.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Cross.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Curve.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Dot.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Polygon.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Rectangle.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Sector.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Symbols.js.map +0 -1
- package/dist/node_modules/recharts/es6/shape/Trapezoid.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/ActiveShapeUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/BarUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/CartesianUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/ChartUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/Constants.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/CssPrefixUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/DOMUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/DataUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/DetectReferenceElementsDomain.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/Events.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/Global.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/IfOverflowMatches.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/LogUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/PolarUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/ReactUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/ReduceCSSCalc.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/ShallowEqual.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/TickUtils.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/calculateViewBox.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/cursor/getCursorPoints.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/cursor/getCursorRectangle.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/cursor/getRadialCursorPoints.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/getEveryNthWithCondition.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/getLegendProps.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/isDomainSpecifiedByUser.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/payload/getUniqPayload.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/tooltip/translate.js.map +0 -1
- package/dist/node_modules/recharts/es6/util/types.js.map +0 -1
- package/dist/node_modules/recharts-scale/es6/getNiceTickValues.js.map +0 -1
- package/dist/node_modules/recharts-scale/es6/util/arithmetic.js.map +0 -1
- package/dist/node_modules/recharts-scale/es6/util/utils.js.map +0 -1
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +0 -1
- package/dist/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
- package/dist/node_modules/victory-vendor/es/d3-scale.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/findElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js.map +0 -1
- package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js.map +0 -1
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +0 -1
- package/dist/planmagnet/PlanMagnetRoot.js.map +0 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +0 -1
- package/dist/planmagnet/PlanMagnetRoutes.js.map +0 -1
- package/dist/planmagnet/activity/activityDescribe.d.ts.map +0 -1
- package/dist/planmagnet/activity/activityDescribe.js.map +0 -1
- package/dist/planmagnet/activity/relativeTime.d.ts.map +0 -1
- package/dist/planmagnet/activity/relativeTime.js.map +0 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.d.ts.map +0 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +0 -1
- package/dist/planmagnet/automation/AutomationExecutionsPanel.d.ts.map +0 -1
- package/dist/planmagnet/automation/AutomationExecutionsPanel.js.map +0 -1
- package/dist/planmagnet/automation/AutomationRuleFields.d.ts.map +0 -1
- package/dist/planmagnet/automation/AutomationRuleFields.js.map +0 -1
- package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +0 -1
- package/dist/planmagnet/automation/automationRuleTypes.js.map +0 -1
- package/dist/planmagnet/board/BoardViewBar.d.ts.map +0 -1
- package/dist/planmagnet/board/BoardViewBar.js.map +0 -1
- package/dist/planmagnet/board/BulkActions.d.ts.map +0 -1
- package/dist/planmagnet/board/BulkActions.js.map +0 -1
- package/dist/planmagnet/board/ProjectBoard.d.ts.map +0 -1
- package/dist/planmagnet/board/ProjectBoard.js.map +0 -1
- package/dist/planmagnet/board/boardViewConfig.d.ts.map +0 -1
- package/dist/planmagnet/board/boardViewConfig.js.map +0 -1
- package/dist/planmagnet/budgets/BudgetControls.d.ts.map +0 -1
- package/dist/planmagnet/budgets/BudgetControls.js.map +0 -1
- package/dist/planmagnet/budgets/ExpenseControls.d.ts.map +0 -1
- package/dist/planmagnet/budgets/ExpenseControls.js.map +0 -1
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.d.ts.map +0 -1
- package/dist/planmagnet/budgets/ProjectBudgetsSummary.js.map +0 -1
- package/dist/planmagnet/budgets/budgetMath.d.ts.map +0 -1
- package/dist/planmagnet/budgets/budgetMath.js.map +0 -1
- package/dist/planmagnet/comments/CommentAttachmentUpload.d.ts.map +0 -1
- package/dist/planmagnet/comments/CommentAttachmentUpload.js.map +0 -1
- package/dist/planmagnet/comments/CommentAttachments.d.ts.map +0 -1
- package/dist/planmagnet/comments/CommentAttachments.js.map +0 -1
- package/dist/planmagnet/comments/CommentBody.d.ts.map +0 -1
- package/dist/planmagnet/comments/CommentBody.js.map +0 -1
- package/dist/planmagnet/comments/CommentThread.d.ts.map +0 -1
- package/dist/planmagnet/comments/CommentThread.js.map +0 -1
- package/dist/planmagnet/comments/MentionComposer.d.ts.map +0 -1
- package/dist/planmagnet/comments/MentionComposer.js.map +0 -1
- package/dist/planmagnet/comments/RoadmapComments.d.ts.map +0 -1
- package/dist/planmagnet/comments/RoadmapComments.js.map +0 -1
- package/dist/planmagnet/comments/TargetComments.d.ts.map +0 -1
- package/dist/planmagnet/comments/TargetComments.js.map +0 -1
- package/dist/planmagnet/comments/WorkItemActivity.d.ts.map +0 -1
- package/dist/planmagnet/comments/WorkItemActivity.js.map +0 -1
- package/dist/planmagnet/comments/WorkItemComments.d.ts.map +0 -1
- package/dist/planmagnet/comments/WorkItemComments.js.map +0 -1
- package/dist/planmagnet/comments/commentAttachmentUploadClient.d.ts.map +0 -1
- package/dist/planmagnet/comments/commentAttachmentUploadClient.js.map +0 -1
- package/dist/planmagnet/comments/commentImageTokens.d.ts.map +0 -1
- package/dist/planmagnet/comments/commentImageTokens.js.map +0 -1
- package/dist/planmagnet/comments/commentTokens.d.ts.map +0 -1
- package/dist/planmagnet/comments/commentTokens.js.map +0 -1
- package/dist/planmagnet/comments/fileDisplay.d.ts.map +0 -1
- package/dist/planmagnet/comments/fileDisplay.js.map +0 -1
- package/dist/planmagnet/comments/useCommentFileUrl.d.ts.map +0 -1
- package/dist/planmagnet/comments/useCommentFileUrl.js.map +0 -1
- package/dist/planmagnet/controls/AutomationRuleControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/AutomationRuleControls.js.map +0 -1
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/CompetitorControls.js.map +0 -1
- package/dist/planmagnet/controls/ConfirmButton.d.ts.map +0 -1
- package/dist/planmagnet/controls/ConfirmButton.js.map +0 -1
- package/dist/planmagnet/controls/CustomFieldControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/CustomFieldControls.js.map +0 -1
- package/dist/planmagnet/controls/CustomFieldValuesPanel.d.ts.map +0 -1
- package/dist/planmagnet/controls/CustomFieldValuesPanel.js.map +0 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/FeatureControls.js.map +0 -1
- package/dist/planmagnet/controls/FeatureTriage.d.ts.map +0 -1
- package/dist/planmagnet/controls/FeatureTriage.js.map +0 -1
- package/dist/planmagnet/controls/FeedbackControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/FeedbackControls.js.map +0 -1
- package/dist/planmagnet/controls/LiveStatus.d.ts.map +0 -1
- package/dist/planmagnet/controls/LiveStatus.js.map +0 -1
- package/dist/planmagnet/controls/MilestoneControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/MilestoneControls.js.map +0 -1
- package/dist/planmagnet/controls/ObjectiveControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/ObjectiveControls.js.map +0 -1
- package/dist/planmagnet/controls/Pickers.d.ts.map +0 -1
- package/dist/planmagnet/controls/Pickers.js.map +0 -1
- package/dist/planmagnet/controls/PortfolioControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/PortfolioControls.js.map +0 -1
- package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/PrioritizationControls.js.map +0 -1
- package/dist/planmagnet/controls/ProgramControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/ProgramControls.js.map +0 -1
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/ProjectControls.js.map +0 -1
- package/dist/planmagnet/controls/QualityGateControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/QualityGateControls.js.map +0 -1
- package/dist/planmagnet/controls/ReleaseControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/ReleaseControls.js.map +0 -1
- package/dist/planmagnet/controls/RiskControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/RiskControls.js.map +0 -1
- package/dist/planmagnet/controls/SyncControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/SyncControls.js.map +0 -1
- package/dist/planmagnet/controls/TemplateControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/TemplateControls.js.map +0 -1
- package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +0 -1
- package/dist/planmagnet/controls/WorkItemControls.d.ts.map +0 -1
- package/dist/planmagnet/controls/WorkItemControls.js.map +0 -1
- package/dist/planmagnet/create/CreateDialogs.d.ts.map +0 -1
- package/dist/planmagnet/create/CreateDialogs.js.map +0 -1
- package/dist/planmagnet/dashboards/DashboardUI.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/DashboardUI.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/DeliveryTimelineCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/DeliveryTimelineCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/ObjectivesProgressCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/ObjectivesProgressCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/PortfolioHealthCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/PortfolioHealthCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/QualityMetricsCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/QualityMetricsCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/RiskSeverityCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/RoadmapHorizonCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/RoadmapHorizonCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/TaskCompletionCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/TaskCompletionCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamCapacityCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamCapacityCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamOverviewCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamOverviewCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamWorkloadCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/TeamWorkloadCard.js.map +0 -1
- package/dist/planmagnet/dashboards/cards/TimeLoggedCard.d.ts.map +0 -1
- package/dist/planmagnet/dashboards/cards/TimeLoggedCard.js.map +0 -1
- package/dist/planmagnet/dependency/DependencyGraph.d.ts.map +0 -1
- package/dist/planmagnet/dependency/DependencyGraph.js.map +0 -1
- package/dist/planmagnet/dependency/DependencyPanel.d.ts.map +0 -1
- package/dist/planmagnet/dependency/DependencyPanel.js.map +0 -1
- package/dist/planmagnet/dependency/GanttChart.d.ts.map +0 -1
- package/dist/planmagnet/dependency/GanttChart.js.map +0 -1
- package/dist/planmagnet/dependency/useProjectWorkItemsGraph.d.ts.map +0 -1
- package/dist/planmagnet/dependency/useProjectWorkItemsGraph.js.map +0 -1
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts.map +0 -1
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js.map +0 -1
- package/dist/planmagnet/docs/DocDiffView.d.ts.map +0 -1
- package/dist/planmagnet/docs/DocDiffView.js.map +0 -1
- package/dist/planmagnet/docs/DocStatusBadge.d.ts.map +0 -1
- package/dist/planmagnet/docs/DocStatusBadge.js.map +0 -1
- package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts.map +0 -1
- package/dist/planmagnet/docs/DocSuggestionsPanel.js.map +0 -1
- package/dist/planmagnet/docs/DocVersionCompare.d.ts.map +0 -1
- package/dist/planmagnet/docs/DocVersionCompare.js.map +0 -1
- package/dist/planmagnet/export/ExportWorkItemsButton.d.ts.map +0 -1
- package/dist/planmagnet/export/ExportWorkItemsButton.js.map +0 -1
- package/dist/planmagnet/export/workItemsCsv.d.ts.map +0 -1
- package/dist/planmagnet/export/workItemsCsv.js.map +0 -1
- package/dist/planmagnet/forecast/DeliveryForecastCard.d.ts.map +0 -1
- package/dist/planmagnet/forecast/DeliveryForecastCard.js.map +0 -1
- package/dist/planmagnet/forecast/ProjectOutlookCard.d.ts.map +0 -1
- package/dist/planmagnet/forecast/ProjectOutlookCard.js.map +0 -1
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.d.ts.map +0 -1
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js.map +0 -1
- package/dist/planmagnet/forecast/ResourceForecastCard.d.ts.map +0 -1
- package/dist/planmagnet/forecast/ResourceForecastCard.js.map +0 -1
- package/dist/planmagnet/forecast/riskFlags.d.ts.map +0 -1
- package/dist/planmagnet/forecast/riskFlags.js.map +0 -1
- package/dist/planmagnet/hooks/useCounts.d.ts.map +0 -1
- package/dist/planmagnet/hooks/useCounts.js.map +0 -1
- package/dist/planmagnet/hooks/useEntityId.d.ts.map +0 -1
- package/dist/planmagnet/hooks/useEntityId.js.map +0 -1
- package/dist/planmagnet/hooks/useLiveRefresh.d.ts.map +0 -1
- package/dist/planmagnet/hooks/useLiveRefresh.js.map +0 -1
- package/dist/planmagnet/hooks/usePresence.d.ts.map +0 -1
- package/dist/planmagnet/hooks/usePresence.js.map +0 -1
- package/dist/planmagnet/hooks/useProjectWorkflow.d.ts.map +0 -1
- package/dist/planmagnet/hooks/useProjectWorkflow.js.map +0 -1
- package/dist/planmagnet/import/exportColumns.d.ts.map +0 -1
- package/dist/planmagnet/import/exportColumns.js.map +0 -1
- package/dist/planmagnet/index.d.ts.map +0 -1
- package/dist/planmagnet/integrations/routes.d.ts.map +0 -1
- package/dist/planmagnet/integrations/routes.js.map +0 -1
- package/dist/planmagnet/integrations/syncTypes.d.ts.map +0 -1
- package/dist/planmagnet/integrations/syncTypes.js.map +0 -1
- package/dist/planmagnet/integrations/useSyncProviderCapabilities.d.ts.map +0 -1
- package/dist/planmagnet/integrations/useSyncProviderCapabilities.js.map +0 -1
- package/dist/planmagnet/links/CodeLinksPanel.d.ts.map +0 -1
- package/dist/planmagnet/links/CodeLinksPanel.js.map +0 -1
- package/dist/planmagnet/links/IssueLinksPanel.d.ts.map +0 -1
- package/dist/planmagnet/links/IssueLinksPanel.js.map +0 -1
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.d.ts.map +0 -1
- package/dist/planmagnet/meetings/MeetingActionItemsPanel.js.map +0 -1
- package/dist/planmagnet/meetings/MeetingsCard.d.ts.map +0 -1
- package/dist/planmagnet/meetings/MeetingsCard.js.map +0 -1
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.d.ts.map +0 -1
- package/dist/planmagnet/meetings/ScheduleCeremoniesDialog.js.map +0 -1
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.d.ts.map +0 -1
- package/dist/planmagnet/meetings/ScheduleMeetingDialog.js.map +0 -1
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.d.ts.map +0 -1
- package/dist/planmagnet/meetings/UnlinkMeetingDialog.js.map +0 -1
- package/dist/planmagnet/meetings/meetingActions.d.ts.map +0 -1
- package/dist/planmagnet/meetings/meetingActions.js.map +0 -1
- package/dist/planmagnet/meetings/meetingGraphql.d.ts.map +0 -1
- package/dist/planmagnet/meetings/meetingGraphql.js.map +0 -1
- package/dist/planmagnet/meetings/meetingModel.d.ts.map +0 -1
- package/dist/planmagnet/meetings/meetingModel.js.map +0 -1
- package/dist/planmagnet/milestones/MilestoneControls.d.ts.map +0 -1
- package/dist/planmagnet/milestones/MilestoneControls.js.map +0 -1
- package/dist/planmagnet/pages/ActivityActivityPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ActivityActivityPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AiActivityPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AiActivityPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AiPlanPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AiPlanPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +0 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DashboardsExecutivePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DashboardsExecutivePagePage.js.map +0 -1
- package/dist/planmagnet/pages/DashboardsLeadershipPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DashboardsLeadershipPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DashboardsProjectManagerPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DashboardsProjectManagerPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DashboardsTeamUtilizationPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DashboardsTeamUtilizationPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/DocsDocsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/DocsDocsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +0 -1
- package/dist/planmagnet/pages/GoalsGoalsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/GoalsGoalsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js.map +0 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +0 -1
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/MeetingsMeetingDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/MeetingsMeetingsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/NotFoundPage.d.ts.map +0 -1
- package/dist/planmagnet/pages/NotFoundPage.js.map +0 -1
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/PortfoliosCreatePortfolioPagePage.js.map +0 -1
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/PortfoliosEditPortfolioPagePage.js.map +0 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/PortfoliosPortfoliosPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsCreateProductPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsCreateRoadmapPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsCustomerSatisfactionPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsCustomerSatisfactionPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsEditProductPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsEditReleasePagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsEditRoadmapPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsFeatureAnalyticsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsPrioritizationPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsProductFeatureDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsProductFeatureDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsProductHierarchyPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsProductHierarchyPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsProductLinesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsProductLinesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsReleaseDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsReleasesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProductsRoadmapsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProgramsCreateProgramPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProgramsEditProgramPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProgramsProgramDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProgramsProgramsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsActiveProjectsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsBudgetDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsCreateProjectPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsCustomFieldsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsGanttPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsGanttPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsMilestoneDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsMilestonesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningEditPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsPlanningPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsQualityGatesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsQualityGatesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ProjectsWorkflowPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ProjectsWorkflowPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ReportsEditReportPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ReportsReportPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ReportsReportPagePage.js.map +0 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/RisksRiskDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/RisksRiskRegisterPagePage.js.map +0 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksImportPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksImportPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksMyDashboardPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksMyDashboardPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksMyWorkPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksMyWorkPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksTasksPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksTimesheetDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TasksTimesheetsPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamCreateTeamPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamCreateTeamPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamInviteMemberPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamInviteMemberPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamTeamDetailPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamTeamEditPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamTeamEditPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TeamTeamsListPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TeamTeamsListPagePage.js.map +0 -1
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TemplatesEditTemplatePagePage.js.map +0 -1
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/TemplatesTemplatesPagePage.js.map +0 -1
- package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.d.ts.map +0 -1
- package/dist/planmagnet/pages/WorkspaceCreateWorkspacePagePage.js.map +0 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js.map +0 -1
- package/dist/planmagnet/pages/analytics/DeliveryKpisCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/MetricsCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/QualityMetricsCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/QualityMetricsCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js.map +0 -1
- package/dist/planmagnet/pages/analytics/StatusFlowCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/StatusFlowCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/ThroughputCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/ThroughputCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/WorkBreakdownCard.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js.map +0 -1
- package/dist/planmagnet/pages/analytics/analyticsRange.d.ts.map +0 -1
- package/dist/planmagnet/pages/analytics/analyticsRange.js.map +0 -1
- package/dist/planmagnet/people/People.d.ts.map +0 -1
- package/dist/planmagnet/people/People.js.map +0 -1
- package/dist/planmagnet/presence/PresenceAvatars.d.ts.map +0 -1
- package/dist/planmagnet/presence/PresenceAvatars.js.map +0 -1
- package/dist/planmagnet/product/FeatureLinkPanels.d.ts.map +0 -1
- package/dist/planmagnet/product/FeatureLinkPanels.js.map +0 -1
- package/dist/planmagnet/product/ProductControls.d.ts.map +0 -1
- package/dist/planmagnet/product/ProductControls.js.map +0 -1
- package/dist/planmagnet/product/ProductFeatureControls.d.ts.map +0 -1
- package/dist/planmagnet/product/ProductFeatureControls.js.map +0 -1
- package/dist/planmagnet/product/ProductFeatureLinkCard.d.ts.map +0 -1
- package/dist/planmagnet/product/ProductFeatureLinkCard.js.map +0 -1
- package/dist/planmagnet/product/ProductLineControls.d.ts.map +0 -1
- package/dist/planmagnet/product/ProductLineControls.js.map +0 -1
- package/dist/planmagnet/product/ProductTeamsPanel.d.ts.map +0 -1
- package/dist/planmagnet/product/ProductTeamsPanel.js.map +0 -1
- package/dist/planmagnet/product/WorkItemProductFeatureChip.d.ts.map +0 -1
- package/dist/planmagnet/product/WorkItemProductFeatureChip.js.map +0 -1
- package/dist/planmagnet/product/hierarchy.d.ts.map +0 -1
- package/dist/planmagnet/product/hierarchy.js.map +0 -1
- package/dist/planmagnet/product/hierarchyOperations.d.ts.map +0 -1
- package/dist/planmagnet/product/hierarchyOperations.js.map +0 -1
- package/dist/planmagnet/product/refusal.d.ts.map +0 -1
- package/dist/planmagnet/product/refusal.js.map +0 -1
- package/dist/planmagnet/product/routes.d.ts.map +0 -1
- package/dist/planmagnet/product/routes.js.map +0 -1
- package/dist/planmagnet/providers/PlanMagnetProvider.d.ts.map +0 -1
- package/dist/planmagnet/providers/PlanMagnetProvider.js.map +0 -1
- package/dist/planmagnet/releases/ReleaseChecklistCard.d.ts.map +0 -1
- package/dist/planmagnet/releases/ReleaseChecklistCard.js.map +0 -1
- package/dist/planmagnet/releases/ReleaseGatesCard.d.ts.map +0 -1
- package/dist/planmagnet/releases/ReleaseGatesCard.js.map +0 -1
- package/dist/planmagnet/releases/ReleaseNotesCard.d.ts.map +0 -1
- package/dist/planmagnet/releases/ReleaseNotesCard.js.map +0 -1
- package/dist/planmagnet/releases/ReleaseReadinessCard.d.ts.map +0 -1
- package/dist/planmagnet/releases/ReleaseReadinessCard.js.map +0 -1
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.d.ts.map +0 -1
- package/dist/planmagnet/releases/ReleaseWorkItemsCard.js.map +0 -1
- package/dist/planmagnet/releases/useReleaseOptions.d.ts.map +0 -1
- package/dist/planmagnet/releases/useReleaseOptions.js.map +0 -1
- package/dist/planmagnet/reports/ExportMenu.d.ts.map +0 -1
- package/dist/planmagnet/reports/ExportMenu.js.map +0 -1
- package/dist/planmagnet/reports/PrintReportView.d.ts.map +0 -1
- package/dist/planmagnet/reports/PrintReportView.js.map +0 -1
- package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts.map +0 -1
- package/dist/planmagnet/reports/ReportBuilderCanvas.js.map +0 -1
- package/dist/planmagnet/reports/ReportBuilderPage.d.ts.map +0 -1
- package/dist/planmagnet/reports/ReportBuilderPage.js.map +0 -1
- package/dist/planmagnet/reports/ReportRunHistory.d.ts.map +0 -1
- package/dist/planmagnet/reports/ReportRunHistory.js.map +0 -1
- package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts.map +0 -1
- package/dist/planmagnet/reports/ReportWidgetRenderer.js.map +0 -1
- package/dist/planmagnet/reports/SchedulesPanel.d.ts.map +0 -1
- package/dist/planmagnet/reports/SchedulesPanel.js.map +0 -1
- package/dist/planmagnet/reports/ShareDialog.d.ts.map +0 -1
- package/dist/planmagnet/reports/ShareDialog.js.map +0 -1
- package/dist/planmagnet/reports/SharedReportPage.d.ts.map +0 -1
- package/dist/planmagnet/reports/SharedReportPage.js.map +0 -1
- package/dist/planmagnet/reports/WidgetEditorDialog.d.ts.map +0 -1
- package/dist/planmagnet/reports/WidgetEditorDialog.js.map +0 -1
- package/dist/planmagnet/reports/reportExportPptx.d.ts.map +0 -1
- package/dist/planmagnet/reports/reportExportPptx.js.map +0 -1
- package/dist/planmagnet/reports/reportExportXlsx.d.ts.map +0 -1
- package/dist/planmagnet/reports/reportExportXlsx.js.map +0 -1
- package/dist/planmagnet/reports/reportGraphql.d.ts.map +0 -1
- package/dist/planmagnet/reports/reportGraphql.js.map +0 -1
- package/dist/planmagnet/reports/reportModel.d.ts.map +0 -1
- package/dist/planmagnet/reports/reportModel.js.map +0 -1
- package/dist/planmagnet/reports/sharedReportRoute.d.ts.map +0 -1
- package/dist/planmagnet/reports/sharedReportRoute.js.map +0 -1
- package/dist/planmagnet/roadmaps/FeatureInitiativeCard.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/FeatureInitiativeCard.js.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.js.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapPresentation.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapPresentation.js.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapReviewPanel.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapReviewPanel.js.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapVersionsPanel.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/RoadmapVersionsPanel.js.map +0 -1
- package/dist/planmagnet/roadmaps/planningFocus.d.ts.map +0 -1
- package/dist/planmagnet/roadmaps/planningFocus.js.map +0 -1
- package/dist/planmagnet/satisfaction/DeliverySatisfactionSection.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/DeliverySatisfactionSection.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionFigures.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionFigures.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionImportDialog.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionImportDialog.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionLinkFields.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionLinkFields.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionReleaseSelect.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionReleaseSelect.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionResponseDialog.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionResponseDialog.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionResponsesTable.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionResponsesTable.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionSummaryCard.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionSummaryCard.js.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionWindowPicker.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/SatisfactionWindowPicker.js.map +0 -1
- package/dist/planmagnet/satisfaction/satisfaction.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/satisfaction.js.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionCsv.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionCsv.js.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionForm.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionForm.js.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionOperations.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/satisfactionOperations.js.map +0 -1
- package/dist/planmagnet/satisfaction/useSatisfactionAccess.d.ts.map +0 -1
- package/dist/planmagnet/satisfaction/useSatisfactionAccess.js.map +0 -1
- package/dist/planmagnet/skills/RequiredSkillsEditor.d.ts.map +0 -1
- package/dist/planmagnet/skills/RequiredSkillsEditor.js.map +0 -1
- package/dist/planmagnet/skills/SkillChips.d.ts.map +0 -1
- package/dist/planmagnet/skills/SkillChips.js.map +0 -1
- package/dist/planmagnet/skills/SkillCoverageCard.d.ts.map +0 -1
- package/dist/planmagnet/skills/SkillCoverageCard.js.map +0 -1
- package/dist/planmagnet/skills/WorkItemRequiredSkills.d.ts.map +0 -1
- package/dist/planmagnet/skills/WorkItemRequiredSkills.js.map +0 -1
- package/dist/planmagnet/skills/skillOperations.d.ts.map +0 -1
- package/dist/planmagnet/skills/skillOperations.js.map +0 -1
- package/dist/planmagnet/skills/skillTags.d.ts.map +0 -1
- package/dist/planmagnet/skills/skillTags.js.map +0 -1
- package/dist/planmagnet/skills/useRequiredSkillsDraft.d.ts.map +0 -1
- package/dist/planmagnet/skills/useRequiredSkillsDraft.js.map +0 -1
- package/dist/planmagnet/sprints/SprintControls.d.ts.map +0 -1
- package/dist/planmagnet/sprints/SprintControls.js.map +0 -1
- package/dist/planmagnet/sprints/SprintDates.d.ts.map +0 -1
- package/dist/planmagnet/sprints/SprintDates.js.map +0 -1
- package/dist/planmagnet/store/planmagnetStore.d.ts.map +0 -1
- package/dist/planmagnet/store/planmagnetStore.js.map +0 -1
- package/dist/planmagnet/team/PendingInvitations.d.ts.map +0 -1
- package/dist/planmagnet/team/PendingInvitations.js.map +0 -1
- package/dist/planmagnet/team/TeamControls.d.ts.map +0 -1
- package/dist/planmagnet/team/TeamControls.js.map +0 -1
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts.map +0 -1
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js.map +0 -1
- package/dist/planmagnet/team/invitationEmail.d.ts.map +0 -1
- package/dist/planmagnet/team/invitationEmail.js.map +0 -1
- package/dist/planmagnet/time/TaskTimePanel.d.ts.map +0 -1
- package/dist/planmagnet/time/TaskTimePanel.js.map +0 -1
- package/dist/planmagnet/time/TimeEntryControls.d.ts.map +0 -1
- package/dist/planmagnet/time/TimeEntryControls.js.map +0 -1
- package/dist/planmagnet/time/TimesheetControls.d.ts.map +0 -1
- package/dist/planmagnet/time/TimesheetControls.js.map +0 -1
- package/dist/planmagnet/time/timeShared.d.ts.map +0 -1
- package/dist/planmagnet/time/timeShared.js.map +0 -1
- package/dist/planmagnet/types/index.d.ts.map +0 -1
- package/dist/planmagnet/utils/cn.d.ts.map +0 -1
- package/dist/planmagnet/utils/cn.js.map +0 -1
- package/dist/planmagnet/utils/email.d.ts.map +0 -1
- package/dist/planmagnet/utils/email.js.map +0 -1
- package/dist/planmagnet/utils/formValidation.d.ts.map +0 -1
- package/dist/planmagnet/utils/formValidation.js.map +0 -1
- package/dist/planmagnet/utils/graphqlErrors.d.ts.map +0 -1
- package/dist/planmagnet/utils/graphqlErrors.js.map +0 -1
- package/dist/planmagnet/utils/lineDiff.d.ts.map +0 -1
- package/dist/planmagnet/utils/lineDiff.js.map +0 -1
- package/dist/planmagnet/utils/mutationResult.d.ts.map +0 -1
- package/dist/planmagnet/utils/mutationResult.js.map +0 -1
- package/dist/planmagnet/utils/navigation.d.ts.map +0 -1
- package/dist/planmagnet/utils/navigation.js.map +0 -1
- package/dist/planmagnet/utils/qualityGateCriteria.d.ts.map +0 -1
- package/dist/planmagnet/utils/qualityGateCriteria.js.map +0 -1
- package/dist/planmagnet/utils/rowNavigation.d.ts.map +0 -1
- package/dist/planmagnet/utils/rowNavigation.js.map +0 -1
- package/dist/planmagnet/utils/statusColor.d.ts.map +0 -1
- package/dist/planmagnet/utils/statusColor.js.map +0 -1
- package/dist/planmagnet/utils/urlParam.d.ts.map +0 -1
- package/dist/planmagnet/utils/urlParam.js.map +0 -1
- package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +0 -1
- package/dist/planmagnet/webhooks/webhookTypes.js.map +0 -1
- package/dist/shared/hooks/useTr.d.ts.map +0 -1
- package/dist/shared/hooks/useTr.js.map +0 -1
- package/dist/shared/utils/i18n.d.ts.map +0 -1
- package/dist/shared/utils/i18n.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductControls.js","names":[],"sources":["../../../src/planmagnet/product/ProductControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Checkbox,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n Badge,\n} from '@burdenoff/fe-libs/ui';\nimport { Archive, ArchiveRestore, Pencil, Plus, Trash2, X } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError, LEAVES_PAGE_CONTEXT } from '../utils/mutationResult';\nimport { mutationErrorMessage } from '../utils/graphqlErrors';\nimport { ConfirmButton, ErrorLine } from '../controls/ConfirmButton';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport { CompetitorSearchSelect } from '../controls/Pickers';\n\n/**\n * Product controls (BOFF-8045). A Product LINKS roadmaps, releases, feature requests and\n * OKR objectives — it never owns their rows (child FKs are nullable, `onDelete: SetNull`\n * server-side) and archiving/deleting a Product never deletes what it links to. Every link\n * mutation here is a pairwise link/unlink (mirrors planmagnetLinkKeyResultToWorkItem in the\n * okr module), not a batch \"set list\" — so adding several candidates at once fires one\n * mutation call per selection.\n */\n\n// ─── Shared refs ────────────────────────────────────────────────────────────\n\nexport interface ProductRoadmapRef {\n id: string;\n name: string;\n}\nexport interface ProductReleaseRef {\n id: string;\n name: string;\n version: string;\n status: string;\n}\nexport interface ProductFeatureRequestRef {\n id: string;\n title: string;\n status: string;\n}\nexport interface ProductObjectiveRef {\n id: string;\n title: string;\n status: string;\n}\nexport interface ProductCompetitorRef {\n id: string;\n name: string;\n description: string | null;\n website: string | null;\n}\n\n/** Every query that lists products or shows a product's detail/links. */\nexport const PRODUCT_QUERIES = ['GetProducts', 'GetProductForEdit', 'GetProductDetail'];\n\n// ─── Header actions (archive / unarchive / delete) ─────────────────────────\n\nconst DELETE_PRODUCT = gql`\n mutation ProductControlsDelete($id: ID!) {\n planmagnetDeleteProduct(id: $id)\n }\n`;\nconst ARCHIVE_PRODUCT = gql`\n mutation ProductControlsArchive($id: ID!) {\n planmagnetArchiveProduct(id: $id) {\n id\n archivedAt\n }\n }\n`;\nconst UNARCHIVE_PRODUCT = gql`\n mutation ProductControlsUnarchive($id: ID!) {\n planmagnetUnarchiveProduct(id: $id) {\n id\n archivedAt\n }\n }\n`;\n\nexport function ProductHeaderActions({\n productId,\n name,\n archivedAt,\n}: {\n productId: string;\n name: string;\n archivedAt: string | null;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [remove, removeState] = useMutation(DELETE_PRODUCT, {\n refetchQueries: PRODUCT_QUERIES,\n context: LEAVES_PAGE_CONTEXT,\n });\n const [archive, archiveState] = useMutation(ARCHIVE_PRODUCT, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [unarchive, unarchiveState] = useMutation(UNARCHIVE_PRODUCT, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: productId } }));\n navigate('/products/products-page');\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The product could not be deleted.');\n }\n };\n\n const onToggleArchive = async () => {\n setError(null);\n try {\n if (archivedAt) {\n await throwOnError(unarchive({ variables: { id: productId } }));\n } else {\n await throwOnError(archive({ variables: { id: productId } }));\n }\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The product could not be updated.');\n }\n };\n\n const archiving = archiveState.loading || unarchiveState.loading;\n\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"product-toggle-archive\"\n disabled={archiving}\n onClick={() => void onToggleArchive()}\n >\n {archivedAt ? (\n <ArchiveRestore className=\"mr-1 h-4 w-4\" />\n ) : (\n <Archive className=\"mr-1 h-4 w-4\" />\n )}\n {archivedAt ? 'Unarchive' : 'Archive'}\n </Button>\n <ConfirmButton\n label=\"Delete\"\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n title={`Delete ${name}?`}\n description=\"Its features are deleted with it. Every linked roadmap, release, feature request and work item stays intact — only its link to this product or to its features is cleared — and removing its teams changes no one's access. This cannot be undone here.\"\n confirmLabel=\"Delete product\"\n destructive\n disabled={removeState.loading}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\n// ─── Roadmaps panel ─────────────────────────────────────────────────────────\n\nconst LINK_PRODUCT_ROADMAP = gql`\n mutation ProductControlsLinkRoadmap($productId: ID!, $roadmapId: ID!) {\n planmagnetLinkProductRoadmap(productId: $productId, roadmapId: $roadmapId) {\n id\n }\n }\n`;\nconst UNLINK_PRODUCT_ROADMAP = gql`\n mutation ProductControlsUnlinkRoadmap($productId: ID!, $roadmapId: ID!) {\n planmagnetUnlinkProductRoadmap(productId: $productId, roadmapId: $roadmapId) {\n id\n }\n }\n`;\nconst PRODUCT_CANDIDATE_ROADMAPS = gql`\n query ProductControlsCandidateRoadmaps($workspaceId: ID!) {\n planmagnetRoadmaps(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n totalCount\n }\n }\n`;\n\nexport function ProductRoadmapsPanel({\n productId,\n roadmaps,\n}: {\n productId: string;\n roadmaps: ProductRoadmapRef[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_ROADMAP, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n const [removingId, setRemovingId] = useState<string | null>(null);\n\n const handleRemove = async (roadmapId: string) => {\n setError(null);\n setRemovingId(roadmapId);\n try {\n await throwOnError(unlink({ variables: { productId, roadmapId } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The roadmap could not be unlinked.');\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-roadmaps\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {roadmaps.length} roadmap{roadmaps.length === 1 ? '' : 's'}\n </p>\n <AddProductRoadmapsDialog productId={productId} existingIds={roadmaps.map((r) => r.id)} />\n </div>\n {error && <ErrorLine message={error} />}\n {roadmaps.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No roadmaps linked to this product yet.\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {roadmaps.map((roadmap) => (\n <li\n key={roadmap.id}\n className=\"flex items-center justify-between gap-2 border rounded-md p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 truncate text-left hover:underline\"\n onClick={() => navigate(detailPath('/products/roadmap-detail-page', roadmap.id))}\n >\n {roadmap.name}\n </button>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Unlink ${roadmap.name} from product`}\n disabled={unlinkState.loading}\n onClick={() => void handleRemove(roadmap.id)}\n >\n {removingId === roadmap.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction AddProductRoadmapsDialog({\n productId,\n existingIds,\n}: {\n productId: string;\n existingIds: string[];\n}) {\n const { workspaceId } = usePlanMagnet();\n const [open, setOpen] = useState(false);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n\n const { data, loading } = useQuery<{\n planmagnetRoadmaps: { items: ProductRoadmapRef[]; totalCount: number };\n }>(PRODUCT_CANDIDATE_ROADMAPS, {\n variables: { workspaceId: workspaceId ?? '' },\n skip: !open || !workspaceId,\n });\n const candidates = (data?.planmagnetRoadmaps.items ?? []).filter(\n (r) => !existingIds.includes(r.id)\n );\n\n const [link, linkState] = useMutation(LINK_PRODUCT_ROADMAP, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const toggle = (id: string, checked: boolean) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (checked) next.add(id);\n else next.delete(id);\n return next;\n });\n\n const reset = () => {\n setSelected(new Set());\n setError(null);\n };\n\n const handleAdd = async () => {\n setError(null);\n try {\n await Promise.all(\n [...selected].map((roadmapId) =>\n throwOnError(link({ variables: { productId, roadmapId } }))\n )\n );\n reset();\n setOpen(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The roadmaps could not be linked.');\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-add-roadmaps\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add roadmap\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Link roadmaps</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Linking a roadmap does not move or copy it — it stays exactly where it is, now also\n reachable from this product.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div\n className=\"max-h-80 overflow-y-auto space-y-1\"\n data-testid=\"product-add-roadmap-candidates\"\n >\n {loading && <p className=\"text-sm text-muted-foreground py-4 text-center\">Loading…</p>}\n {!loading && candidates.length === 0 && (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n Every roadmap in this workspace is already linked to this product.\n </p>\n )}\n {candidates.map((roadmap) => {\n const inputId = `product-add-roadmap-${roadmap.id}`;\n return (\n <label\n key={roadmap.id}\n htmlFor={inputId}\n className=\"flex items-center gap-3 border rounded-md p-2 text-sm cursor-pointer hover:bg-muted\"\n >\n <Checkbox\n id={inputId}\n checked={selected.has(roadmap.id)}\n onCheckedChange={(checked) => toggle(roadmap.id, checked === true)}\n />\n <span className=\"min-w-0 flex-1 truncate\">{roadmap.name}</span>\n </label>\n );\n })}\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void handleAdd()}\n disabled={selected.size === 0 || linkState.loading}\n data-testid=\"product-add-roadmaps-confirm\"\n >\n {linkState.loading\n ? 'Linking…'\n : `Link ${selected.size} roadmap${selected.size === 1 ? '' : 's'}`}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── Releases panel ─────────────────────────────────────────────────────────\n\nconst LINK_PRODUCT_RELEASE = gql`\n mutation ProductControlsLinkRelease($productId: ID!, $releaseId: ID!) {\n planmagnetLinkProductRelease(productId: $productId, releaseId: $releaseId) {\n id\n }\n }\n`;\nconst UNLINK_PRODUCT_RELEASE = gql`\n mutation ProductControlsUnlinkRelease($productId: ID!, $releaseId: ID!) {\n planmagnetUnlinkProductRelease(productId: $productId, releaseId: $releaseId) {\n id\n }\n }\n`;\nconst PRODUCT_CANDIDATE_RELEASES = gql`\n query ProductControlsCandidateReleases($workspaceId: ID!) {\n planmagnetReleases(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n version\n status\n }\n totalCount\n }\n }\n`;\n\nexport function ProductReleasesPanel({\n productId,\n releases,\n}: {\n productId: string;\n releases: ProductReleaseRef[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_RELEASE, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n const [removingId, setRemovingId] = useState<string | null>(null);\n\n const handleRemove = async (releaseId: string) => {\n setError(null);\n setRemovingId(releaseId);\n try {\n await throwOnError(unlink({ variables: { productId, releaseId } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The release could not be unlinked.');\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-releases\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {releases.length} release{releases.length === 1 ? '' : 's'}\n </p>\n <AddProductReleasesDialog productId={productId} existingIds={releases.map((r) => r.id)} />\n </div>\n {error && <ErrorLine message={error} />}\n {releases.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No releases linked to this product yet.\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {releases.map((release) => (\n <li\n key={release.id}\n className=\"flex items-center justify-between gap-2 border rounded-md p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 truncate text-left hover:underline\"\n onClick={() => navigate(detailPath('/products/release-detail-page', release.id))}\n >\n <span className=\"text-muted-foreground mr-2\">{release.version}</span>\n {release.name}\n </button>\n <div className=\"flex items-center gap-2 shrink-0\">\n <Badge variant=\"outline\" className=\"text-xs capitalize\">\n {enumLabel(release.status)}\n </Badge>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Unlink ${release.name} from product`}\n disabled={unlinkState.loading}\n onClick={() => void handleRemove(release.id)}\n >\n {removingId === release.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction AddProductReleasesDialog({\n productId,\n existingIds,\n}: {\n productId: string;\n existingIds: string[];\n}) {\n const { workspaceId } = usePlanMagnet();\n const [open, setOpen] = useState(false);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n\n const { data, loading } = useQuery<{\n planmagnetReleases: { items: ProductReleaseRef[]; totalCount: number };\n }>(PRODUCT_CANDIDATE_RELEASES, {\n variables: { workspaceId: workspaceId ?? '' },\n skip: !open || !workspaceId,\n });\n const candidates = (data?.planmagnetReleases.items ?? []).filter(\n (r) => !existingIds.includes(r.id)\n );\n\n const [link, linkState] = useMutation(LINK_PRODUCT_RELEASE, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const toggle = (id: string, checked: boolean) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (checked) next.add(id);\n else next.delete(id);\n return next;\n });\n\n const reset = () => {\n setSelected(new Set());\n setError(null);\n };\n\n const handleAdd = async () => {\n setError(null);\n try {\n await Promise.all(\n [...selected].map((releaseId) =>\n throwOnError(link({ variables: { productId, releaseId } }))\n )\n );\n reset();\n setOpen(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The releases could not be linked.');\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-add-releases\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add release\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Link releases</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Linking a release does not move or copy it — it stays exactly where it is, now also\n reachable from this product.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div\n className=\"max-h-80 overflow-y-auto space-y-1\"\n data-testid=\"product-add-release-candidates\"\n >\n {loading && <p className=\"text-sm text-muted-foreground py-4 text-center\">Loading…</p>}\n {!loading && candidates.length === 0 && (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n Every release in this workspace is already linked to this product.\n </p>\n )}\n {candidates.map((release) => {\n const inputId = `product-add-release-${release.id}`;\n return (\n <label\n key={release.id}\n htmlFor={inputId}\n className=\"flex items-center gap-3 border rounded-md p-2 text-sm cursor-pointer hover:bg-muted\"\n >\n <Checkbox\n id={inputId}\n checked={selected.has(release.id)}\n onCheckedChange={(checked) => toggle(release.id, checked === true)}\n />\n <span className=\"min-w-0 flex-1 truncate\">\n <span className=\"text-muted-foreground mr-2\">{release.version}</span>\n {release.name}\n </span>\n </label>\n );\n })}\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void handleAdd()}\n disabled={selected.size === 0 || linkState.loading}\n data-testid=\"product-add-releases-confirm\"\n >\n {linkState.loading\n ? 'Linking…'\n : `Link ${selected.size} release${selected.size === 1 ? '' : 's'}`}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── Feature requests panel ─────────────────────────────────────────────────\n\nconst LINK_PRODUCT_FEATURE_REQUEST = gql`\n mutation ProductControlsLinkFeatureRequest($productId: ID!, $featureRequestId: ID!) {\n planmagnetLinkProductFeatureRequest(\n productId: $productId\n featureRequestId: $featureRequestId\n ) {\n id\n }\n }\n`;\nconst UNLINK_PRODUCT_FEATURE_REQUEST = gql`\n mutation ProductControlsUnlinkFeatureRequest($productId: ID!, $featureRequestId: ID!) {\n planmagnetUnlinkProductFeatureRequest(\n productId: $productId\n featureRequestId: $featureRequestId\n ) {\n id\n }\n }\n`;\nconst PRODUCT_CANDIDATE_FEATURE_REQUESTS = gql`\n query ProductControlsCandidateFeatureRequests($workspaceId: ID!) {\n planmagnetFeatureRequests(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n title\n status\n }\n totalCount\n }\n }\n`;\n\nexport function ProductFeatureRequestsPanel({\n productId,\n featureRequests,\n}: {\n productId: string;\n featureRequests: ProductFeatureRequestRef[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_FEATURE_REQUEST, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n const [removingId, setRemovingId] = useState<string | null>(null);\n\n const handleRemove = async (featureRequestId: string) => {\n setError(null);\n setRemovingId(featureRequestId);\n try {\n await throwOnError(unlink({ variables: { productId, featureRequestId } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The feature request could not be unlinked.');\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-feature-requests\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {featureRequests.length} feature request{featureRequests.length === 1 ? '' : 's'}\n </p>\n <AddProductFeatureRequestsDialog\n productId={productId}\n existingIds={featureRequests.map((f) => f.id)}\n />\n </div>\n {error && <ErrorLine message={error} />}\n {featureRequests.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No feature requests linked to this product yet.\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {featureRequests.map((feature) => (\n <li\n key={feature.id}\n className=\"flex items-center justify-between gap-2 border rounded-md p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 truncate text-left hover:underline\"\n onClick={() => navigate(detailPath('/products/feature-detail-page', feature.id))}\n >\n {feature.title}\n </button>\n <div className=\"flex items-center gap-2 shrink-0\">\n <Badge variant=\"secondary\" className=\"text-xs capitalize\">\n {enumLabel(feature.status)}\n </Badge>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Unlink ${feature.title} from product`}\n disabled={unlinkState.loading}\n onClick={() => void handleRemove(feature.id)}\n >\n {removingId === feature.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction AddProductFeatureRequestsDialog({\n productId,\n existingIds,\n}: {\n productId: string;\n existingIds: string[];\n}) {\n const { workspaceId } = usePlanMagnet();\n const [open, setOpen] = useState(false);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n\n const { data, loading } = useQuery<{\n planmagnetFeatureRequests: { items: ProductFeatureRequestRef[]; totalCount: number };\n }>(PRODUCT_CANDIDATE_FEATURE_REQUESTS, {\n variables: { workspaceId: workspaceId ?? '' },\n skip: !open || !workspaceId,\n });\n const candidates = (data?.planmagnetFeatureRequests.items ?? []).filter(\n (f) => !existingIds.includes(f.id)\n );\n\n const [link, linkState] = useMutation(LINK_PRODUCT_FEATURE_REQUEST, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const toggle = (id: string, checked: boolean) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (checked) next.add(id);\n else next.delete(id);\n return next;\n });\n\n const reset = () => {\n setSelected(new Set());\n setError(null);\n };\n\n const handleAdd = async () => {\n setError(null);\n try {\n await Promise.all(\n [...selected].map((featureRequestId) =>\n throwOnError(link({ variables: { productId, featureRequestId } }))\n )\n );\n reset();\n setOpen(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The feature requests could not be linked.');\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-add-feature-requests\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add feature request\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Link feature requests</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Linking a feature request does not move or copy it — it stays exactly where it is, now\n also reachable from this product.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div\n className=\"max-h-80 overflow-y-auto space-y-1\"\n data-testid=\"product-add-feature-request-candidates\"\n >\n {loading && <p className=\"text-sm text-muted-foreground py-4 text-center\">Loading…</p>}\n {!loading && candidates.length === 0 && (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n Every feature request in this workspace is already linked to this product.\n </p>\n )}\n {candidates.map((feature) => {\n const inputId = `product-add-feature-${feature.id}`;\n return (\n <label\n key={feature.id}\n htmlFor={inputId}\n className=\"flex items-center gap-3 border rounded-md p-2 text-sm cursor-pointer hover:bg-muted\"\n >\n <Checkbox\n id={inputId}\n checked={selected.has(feature.id)}\n onCheckedChange={(checked) => toggle(feature.id, checked === true)}\n />\n <span className=\"min-w-0 flex-1 truncate\">{feature.title}</span>\n </label>\n );\n })}\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void handleAdd()}\n disabled={selected.size === 0 || linkState.loading}\n data-testid=\"product-add-feature-requests-confirm\"\n >\n {linkState.loading\n ? 'Linking…'\n : `Link ${selected.size} request${selected.size === 1 ? '' : 's'}`}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── Objectives (OKR) panel ─────────────────────────────────────────────────\n// Product<->Objective is a true many-to-many join (ProductObjectiveLink), same pairwise-link\n// shape as planmagnetLinkKeyResultToWorkItem. Unlink returns Boolean!, not Product! (§4).\n\nconst LINK_PRODUCT_OBJECTIVE = gql`\n mutation ProductControlsLinkObjective($productId: ID!, $objectiveId: ID!) {\n planmagnetLinkProductObjective(productId: $productId, objectiveId: $objectiveId) {\n id\n }\n }\n`;\nconst UNLINK_PRODUCT_OBJECTIVE = gql`\n mutation ProductControlsUnlinkObjective($productId: ID!, $objectiveId: ID!) {\n planmagnetUnlinkProductObjective(productId: $productId, objectiveId: $objectiveId)\n }\n`;\nconst PRODUCT_CANDIDATE_OBJECTIVES = gql`\n query ProductControlsCandidateObjectives($workspaceId: ID!) {\n planmagnetObjectives(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n title\n status\n }\n totalCount\n }\n }\n`;\n\nexport function ProductObjectivesPanel({\n productId,\n objectives,\n}: {\n productId: string;\n objectives: ProductObjectiveRef[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_OBJECTIVE, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n const [removingId, setRemovingId] = useState<string | null>(null);\n\n const handleRemove = async (objectiveId: string) => {\n setError(null);\n setRemovingId(objectiveId);\n try {\n await throwOnError(unlink({ variables: { productId, objectiveId } }));\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The objective could not be unlinked.');\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-objectives\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {objectives.length} objective{objectives.length === 1 ? '' : 's'}\n </p>\n <AddProductObjectivesDialog\n productId={productId}\n existingIds={objectives.map((o) => o.id)}\n />\n </div>\n {error && <ErrorLine message={error} />}\n {objectives.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No OKR objectives linked to this product yet.\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {objectives.map((objective) => (\n <li\n key={objective.id}\n className=\"flex items-center justify-between gap-2 border rounded-md p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 truncate text-left hover:underline\"\n onClick={() => navigate(`/goals/objective-detail-page?objectiveId=${objective.id}`)}\n >\n {objective.title}\n </button>\n <div className=\"flex items-center gap-2 shrink-0\">\n <Badge variant=\"secondary\" className=\"text-xs capitalize\">\n {enumLabel(objective.status)}\n </Badge>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={`Unlink ${objective.title} from product`}\n disabled={unlinkState.loading}\n onClick={() => void handleRemove(objective.id)}\n >\n {removingId === objective.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n\nfunction AddProductObjectivesDialog({\n productId,\n existingIds,\n}: {\n productId: string;\n existingIds: string[];\n}) {\n const { workspaceId } = usePlanMagnet();\n const [open, setOpen] = useState(false);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n\n const { data, loading } = useQuery<{\n planmagnetObjectives: { items: ProductObjectiveRef[]; totalCount: number };\n }>(PRODUCT_CANDIDATE_OBJECTIVES, {\n variables: { workspaceId: workspaceId ?? '' },\n skip: !open || !workspaceId,\n });\n const candidates = (data?.planmagnetObjectives.items ?? []).filter(\n (o) => !existingIds.includes(o.id)\n );\n\n const [link, linkState] = useMutation(LINK_PRODUCT_OBJECTIVE, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const toggle = (id: string, checked: boolean) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (checked) next.add(id);\n else next.delete(id);\n return next;\n });\n\n const reset = () => {\n setSelected(new Set());\n setError(null);\n };\n\n const handleAdd = async () => {\n setError(null);\n try {\n await Promise.all(\n [...selected].map((objectiveId) =>\n throwOnError(link({ variables: { productId, objectiveId } }))\n )\n );\n reset();\n setOpen(false);\n } catch (e) {\n setError(e instanceof Error ? e.message : 'The objectives could not be linked.');\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-add-objectives\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add objective\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Link OKR objectives</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Re-linking an objective that is already linked is a no-op, not an error.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div\n className=\"max-h-80 overflow-y-auto space-y-1\"\n data-testid=\"product-add-objective-candidates\"\n >\n {loading && <p className=\"text-sm text-muted-foreground py-4 text-center\">Loading…</p>}\n {!loading && candidates.length === 0 && (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n Every objective in this workspace is already linked to this product.\n </p>\n )}\n {candidates.map((objective) => {\n const inputId = `product-add-objective-${objective.id}`;\n return (\n <label\n key={objective.id}\n htmlFor={inputId}\n className=\"flex items-center gap-3 border rounded-md p-2 text-sm cursor-pointer hover:bg-muted\"\n >\n <Checkbox\n id={inputId}\n checked={selected.has(objective.id)}\n onCheckedChange={(checked) => toggle(objective.id, checked === true)}\n />\n <span className=\"min-w-0 flex-1 truncate\">{objective.title}</span>\n </label>\n );\n })}\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void handleAdd()}\n disabled={selected.size === 0 || linkState.loading}\n data-testid=\"product-add-objectives-confirm\"\n >\n {linkState.loading\n ? 'Linking…'\n : `Link ${selected.size} objective${selected.size === 1 ? '' : 's'}`}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── About this product (PRM-02) ────────────────────────────────────────────\n\nconst UPDATE_PRODUCT_INFO = gql`\n mutation ProductControlsUpdateInfo($id: ID!, $input: PlanmagnetUpdateProductInput!) {\n planmagnetUpdateProduct(id: $id, input: $input) {\n id\n mission\n valueProposition\n businessModel\n targetSegments\n }\n }\n`;\n\nconst MAX_ABOUT_TEXT = 2000;\nconst MAX_SEGMENTS = 20;\nconst MAX_SEGMENT_LENGTH = 120;\n\nexport interface ProductAboutValues {\n id: string;\n mission: string | null;\n valueProposition: string | null;\n businessModel: string | null;\n targetSegments: string[];\n}\n\n/**\n * A tag-style editor for `Product.targetSegments` (PRM-02): type a segment, Enter or the + button adds it as a\n * chip, its own X removes it. The server enforces at most 20 entries of at most 120 characters each — this\n * enforces the same limits client-side so a refusal never reaches the server for an obviously-oversized list.\n */\nfunction SegmentsEditor({\n value,\n onChange,\n disabled,\n}: {\n value: string[];\n onChange: (next: string[]) => void;\n disabled?: boolean;\n}) {\n const [draft, setDraft] = useState('');\n const atLimit = value.length >= MAX_SEGMENTS;\n const trimmed = draft.trim();\n const canAdd =\n !disabled &&\n !atLimit &&\n trimmed !== '' &&\n trimmed.length <= MAX_SEGMENT_LENGTH &&\n !value.includes(trimmed);\n\n const add = () => {\n if (!canAdd) return;\n onChange([...value, trimmed]);\n setDraft('');\n };\n const remove = (segment: string) => onChange(value.filter((s) => s !== segment));\n\n return (\n <div className=\"space-y-2\" data-testid=\"product-segments\">\n <div className=\"flex flex-wrap gap-1\">\n {value.length === 0 && (\n <span className=\"text-xs text-muted-foreground\">No target segments yet.</span>\n )}\n {value.map((segment) => (\n <Badge key={segment} variant=\"secondary\" className=\"gap-1 pr-1\">\n {segment}\n {!disabled && (\n <button\n type=\"button\"\n aria-label={`Remove ${segment}`}\n onClick={() => remove(segment)}\n className=\"rounded-full hover:bg-muted\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </Badge>\n ))}\n </div>\n {!disabled && (\n <div className=\"flex items-center gap-2\">\n <Input\n aria-label=\"Add a target segment\"\n placeholder={atLimit ? `Limit reached (${MAX_SEGMENTS})` : 'e.g. Mid-market SaaS teams'}\n value={draft}\n disabled={atLimit}\n maxLength={MAX_SEGMENT_LENGTH}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n add();\n }\n }}\n />\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n aria-label=\"Add segment\"\n disabled={!canAdd}\n onClick={add}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n )}\n {!disabled && (\n <p className=\"text-xs text-muted-foreground\">\n {value.length}/{MAX_SEGMENTS} segments, up to {MAX_SEGMENT_LENGTH} characters each.\n </p>\n )}\n </div>\n );\n}\n\n/**\n * The product detail page's \"About this product\" section (PRM-02): mission, value proposition, business model\n * and target segments, shown read-only with an inline \"Edit\" toggle for the four fields. Mirrors\n * `FeaturePrioritizationCard`'s own stays-mounted-across-save shape (not a dialog) so a validation refusal from\n * the server surfaces right where the fields are, and the saved values show immediately without navigating.\n */\nexport function ProductAboutPanel({ product }: { product: ProductAboutValues }) {\n const initial = {\n mission: product.mission ?? '',\n valueProposition: product.valueProposition ?? '',\n businessModel: product.businessModel ?? '',\n targetSegments: product.targetSegments,\n };\n const [editing, setEditing] = useState(false);\n const [form, setForm] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n const [update, state] = useMutation(UPDATE_PRODUCT_INFO, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n\n const startEdit = () => {\n setForm(initial);\n setError(null);\n setEditing(true);\n };\n\n const textOverLimit = [form.mission, form.valueProposition, form.businessModel].some(\n (v) => v.length > MAX_ABOUT_TEXT\n );\n const segmentsValid =\n form.targetSegments.length <= MAX_SEGMENTS &&\n form.targetSegments.every((s) => s.length <= MAX_SEGMENT_LENGTH);\n const canSave = !textOverLimit && segmentsValid && !state.loading;\n\n const save = async () => {\n setError(null);\n const text = (v: string) => (v.trim() ? v.trim() : null);\n try {\n await throwOnError(\n update({\n variables: {\n id: product.id,\n input: {\n mission: text(form.mission),\n valueProposition: text(form.valueProposition),\n businessModel: text(form.businessModel),\n targetSegments: form.targetSegments,\n },\n },\n })\n );\n setEditing(false);\n } catch (e) {\n setError(mutationErrorMessage(e, 'The product information could not be saved.'));\n }\n };\n\n const textareaClass =\n 'mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[72px]';\n\n return (\n <Card data-testid=\"product-info\">\n <CardHeader className=\"flex flex-row items-center justify-between gap-2\">\n <CardTitle>About this product</CardTitle>\n {!editing && (\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-info-edit\" onClick={startEdit}>\n <Pencil className=\"mr-1 h-4 w-4\" />\n Edit\n </Button>\n )}\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {!editing ? (\n <>\n <div>\n <p className=\"text-xs font-medium text-muted-foreground\">Mission</p>\n <p className=\"text-sm whitespace-pre-wrap\">{product.mission || 'Not set'}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium text-muted-foreground\">Value proposition</p>\n <p className=\"text-sm whitespace-pre-wrap\">{product.valueProposition || 'Not set'}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium text-muted-foreground\">Business model</p>\n <p className=\"text-sm whitespace-pre-wrap\">{product.businessModel || 'Not set'}</p>\n </div>\n <div>\n <p className=\"text-xs font-medium text-muted-foreground\">Target segments</p>\n <div className=\"mt-1\">\n <SegmentsEditor value={product.targetSegments} onChange={() => {}} disabled />\n </div>\n </div>\n </>\n ) : (\n <>\n <div>\n <label htmlFor=\"product-info-mission\" className=\"text-sm font-medium\">\n Mission\n </label>\n <textarea\n id=\"product-info-mission\"\n className={textareaClass}\n maxLength={MAX_ABOUT_TEXT}\n value={form.mission}\n onChange={(e) => setForm({ ...form, mission: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"product-info-value-proposition\" className=\"text-sm font-medium\">\n Value proposition\n </label>\n <textarea\n id=\"product-info-value-proposition\"\n className={textareaClass}\n maxLength={MAX_ABOUT_TEXT}\n value={form.valueProposition}\n onChange={(e) => setForm({ ...form, valueProposition: e.target.value })}\n />\n </div>\n <div>\n <label htmlFor=\"product-info-business-model\" className=\"text-sm font-medium\">\n Business model\n </label>\n <textarea\n id=\"product-info-business-model\"\n className={textareaClass}\n maxLength={MAX_ABOUT_TEXT}\n value={form.businessModel}\n onChange={(e) => setForm({ ...form, businessModel: e.target.value })}\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Target segments</label>\n <div className=\"mt-1\">\n <SegmentsEditor\n value={form.targetSegments}\n onChange={(targetSegments) => setForm({ ...form, targetSegments })}\n />\n </div>\n </div>\n {error && <ErrorLine message={error} />}\n <div className=\"flex justify-end gap-2\">\n <Button size=\"sm\" variant=\"outline\" onClick={() => setEditing(false)}>\n Cancel\n </Button>\n <Button\n size=\"sm\"\n data-testid=\"product-info-save\"\n disabled={!canSave}\n onClick={() => void save()}\n >\n {state.loading ? 'Saving…' : 'Save'}\n </Button>\n </div>\n </>\n )}\n </CardContent>\n </Card>\n );\n}\n\n// ─── Competitive landscape (PRM-02) ─────────────────────────────────────────\n\nconst LINK_PRODUCT_COMPETITOR = gql`\n mutation ProductControlsLinkCompetitor($productId: ID!, $competitorId: ID!) {\n planmagnetLinkProductCompetitor(productId: $productId, competitorId: $competitorId) {\n id\n }\n }\n`;\nconst UNLINK_PRODUCT_COMPETITOR = gql`\n mutation ProductControlsUnlinkCompetitor($productId: ID!, $competitorId: ID!) {\n planmagnetUnlinkProductCompetitor(productId: $productId, competitorId: $competitorId)\n }\n`;\n\n/**\n * The product detail page's \"Competitive landscape\" panel (PRM-02): the competitors linked to this product, a\n * picker to link another from the workspace directory (`CompetitorSearchSelect`, shared with the feature\n * request detail page's own competitor panel), and an unlink confirm per row — unlike the feature request\n * panel's plain X, PRM-02 asks for a confirm step here since a product's competitive landscape is reviewed\n * material, not a quick per-request note.\n */\nexport function ProductCompetitorsPanel({\n productId,\n competitors,\n}: {\n productId: string;\n competitors: ProductCompetitorRef[];\n}) {\n const navigate = usePlanMagnetNavigate();\n const [addCompetitorId, setAddCompetitorId] = useState('');\n const [link, linkState] = useMutation(LINK_PRODUCT_COMPETITOR, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_COMPETITOR, {\n refetchQueries: PRODUCT_QUERIES,\n awaitRefetchQueries: true,\n });\n const [error, setError] = useState<string | null>(null);\n\n const onAdd = async () => {\n if (!addCompetitorId) return;\n setError(null);\n try {\n await throwOnError(link({ variables: { productId, competitorId: addCompetitorId } }));\n setAddCompetitorId('');\n } catch (e) {\n setError(mutationErrorMessage(e, 'The competitor could not be linked.'));\n }\n };\n const onRemove = async (competitorId: string) => {\n setError(null);\n try {\n await throwOnError(unlink({ variables: { productId, competitorId } }));\n } catch (e) {\n setError(mutationErrorMessage(e, 'The competitor could not be unlinked.'));\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-competitors\">\n {competitors.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No competitors linked to this product yet.\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {competitors.map((comp) => (\n <li\n key={comp.id}\n className=\"flex items-center justify-between gap-2 border rounded-md p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 flex-1 text-left truncate hover:underline\"\n onClick={() => navigate(detailPath('/products/competitor-detail-page', comp.id))}\n >\n {comp.name}\n {comp.website && <span className=\"ml-2 text-xs text-primary\">{comp.website}</span>}\n </button>\n <ConfirmButton\n label=\"\"\n ariaLabel={`Unlink ${comp.name} from this product`}\n testId=\"product-competitor-unlink\"\n variant=\"outline\"\n icon={<X className=\"h-4 w-4\" />}\n title={`Unlink ${comp.name}?`}\n description=\"The competitor stays in the workspace directory — only its link to this product is removed.\"\n confirmLabel=\"Unlink\"\n destructive\n disabled={unlinkState.loading}\n onConfirm={() => void onRemove(comp.id)}\n />\n </li>\n ))}\n </ul>\n )}\n <div className=\"flex items-start gap-2 pt-2 border-t\">\n <div className=\"flex-1\">\n <CompetitorSearchSelect\n id=\"product-add-competitor\"\n value={addCompetitorId}\n onChange={setAddCompetitorId}\n exclude={competitors.map((c) => c.id)}\n />\n </div>\n <Button\n size=\"sm\"\n data-testid=\"product-competitor-link\"\n disabled={!addCompetitorId || linkState.loading}\n onClick={() => void onAdd()}\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n Add\n </Button>\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductFeatureControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/ProductFeatureControls.tsx"],"names":[],"mappings":"AAsCA;;;;;GAKG;AAEH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAiBD,wBAAgB,yBAAyB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,2CAUvE;AAID;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,OAAO,EACP,QAAgB,GACjB,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,2CAiMA;AAID,wBAAgB,2BAA2B,CAAC,EAC1C,OAAO,EACP,SAAS,EACT,YAAY,GACb,EAAE;IACD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB,2CAwFA;AAiBD,iGAAiG;AACjG,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,eAAe,GAChB,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;CAC1B,2CAwHA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductFeatureControls.js","names":[],"sources":["../../../src/planmagnet/product/ProductFeatureControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Button,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Archive, ArchiveRestore, Pencil, Plus, Puzzle, Trash2 } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ConfirmButton, ErrorLine } from '../controls/ConfirmButton';\nimport { AssigneeSelect, enumLabel } from '../controls/WorkItemControls';\nimport { LEAVES_PAGE_CONTEXT, throwOnError } from '../utils/mutationResult';\nimport { detailPath } from '../utils/rowNavigation';\nimport {\n PRODUCT_FEATURE_STATUSES,\n changedFields,\n normalizeText,\n productFeatureStatusVariant,\n} from './hierarchy';\nimport {\n ARCHIVE_PRODUCT_FEATURE,\n CREATE_PRODUCT_FEATURE,\n DELETE_PRODUCT_FEATURE,\n PRODUCT_FEATURES_LIST,\n PRODUCT_FEATURE_QUERIES,\n UNARCHIVE_PRODUCT_FEATURE,\n UPDATE_PRODUCT_FEATURE,\n} from './hierarchyOperations';\nimport { refusalMessage } from './refusal';\n\n/**\n * Product features (PRM-01): what a product team decided to build — not a feature request, which is customer\n * feedback asking for something and may point at the feature that addresses it. A feature belongs to one product\n * for good, links EPIC work items (stories hang off their epics) and the requests it answers. Archiving keeps every\n * link; deleting removes only the links — never a request or a work item.\n */\n\nexport interface ProductFeatureValues {\n id: string;\n productId: string;\n name: string;\n description: string | null;\n status: string;\n ownerId: string | null;\n archivedAt: string | null;\n}\n\nconst textareaClass =\n 'mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[72px]';\nconst selectClass =\n 'mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60';\n\nconst writeOptions = { refetchQueries: PRODUCT_FEATURE_QUERIES, awaitRefetchQueries: true };\n\nfunction useForbiddenText() {\n const tr = useTr();\n return tr(\n 'planmagnet.productFeatures.errors.forbidden',\n 'Your role cannot change this product’s features.'\n );\n}\n\nexport function ProductFeatureStatusBadge({ status }: { status: string }) {\n return (\n <Badge\n variant={productFeatureStatusVariant(status)}\n className=\"text-xs\"\n data-testid=\"product-feature-status\"\n >\n {enumLabel(status)}\n </Badge>\n );\n}\n\n// ─── Create / edit ──────────────────────────────────────────────────────────\n\n/**\n * Create a feature under `productId` (no `feature`) or edit one: name, description, status and owner. An edit sends\n * only what changed; an emptied description or a cleared owner is sent as null, which clears it. Status always has\n * a value — the service refuses to clear it.\n */\nexport function ProductFeatureFormDialog({\n productId,\n feature,\n disabled = false,\n}: {\n productId: string;\n feature?: ProductFeatureValues;\n disabled?: boolean;\n}) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const { currentUser } = usePlanMagnet();\n const initial = {\n name: feature?.name ?? '',\n description: feature?.description ?? '',\n status: feature?.status ?? 'BACKLOG',\n // A new feature is owned by whoever creates it unless they pick someone else (or nobody).\n ownerId: feature ? (feature.ownerId ?? '') : (currentUser?.id ?? ''),\n };\n const [open, setOpen] = useState(false);\n const [form, setForm] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n const [create, createState] = useMutation(CREATE_PRODUCT_FEATURE, writeOptions);\n const [update, updateState] = useMutation(UPDATE_PRODUCT_FEATURE, writeOptions);\n const saving = createState.loading || updateState.loading;\n const canSave = form.name.trim() !== '' && !saving;\n const idPrefix = feature\n ? `product-feature-edit-${feature.id}`\n : `product-feature-new-${productId}`;\n // A stored status this list does not know (newer data) stays selectable rather than silently showing another.\n const statuses: readonly string[] = (PRODUCT_FEATURE_STATUSES as readonly string[]).includes(\n form.status\n )\n ? PRODUCT_FEATURE_STATUSES\n : [form.status, ...PRODUCT_FEATURE_STATUSES];\n\n const save = async () => {\n setError(null);\n const next = {\n name: form.name.trim(),\n description: normalizeText(form.description),\n status: form.status,\n ownerId: form.ownerId || null,\n };\n try {\n if (feature) {\n const before = {\n name: feature.name.trim(),\n description: normalizeText(feature.description ?? ''),\n status: feature.status,\n ownerId: feature.ownerId,\n };\n const input = changedFields(before, next);\n if (Object.keys(input).length > 0) {\n await throwOnError(update({ variables: { id: feature.id, input } }));\n }\n } else {\n await throwOnError(\n create({\n variables: {\n input: {\n productId,\n name: next.name,\n status: next.status,\n ...(next.description ? { description: next.description } : {}),\n ...(next.ownerId ? { ownerId: next.ownerId } : {}),\n },\n },\n })\n );\n }\n setOpen(false);\n } catch (e) {\n setError(\n refusalMessage(\n e,\n feature\n ? tr('planmagnet.productFeatures.errors.save', 'The feature could not be saved.')\n : tr('planmagnet.productFeatures.errors.create', 'The feature could not be created.'),\n forbidden\n )\n );\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) setForm(initial);\n else setError(null);\n }}\n >\n <ResponsiveDialogTrigger asChild>\n {feature ? (\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-feature-edit\">\n <Pencil className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productFeatures.actions.edit', 'Edit')}\n </Button>\n ) : (\n <Button size=\"sm\" disabled={disabled} data-testid=\"product-feature-new\">\n <Plus className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productFeatures.actions.new', 'New feature')}\n </Button>\n )}\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {feature\n ? tr('planmagnet.productFeatures.dialog.editTitle', 'Edit feature')\n : tr('planmagnet.productFeatures.dialog.newTitle', 'New feature')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {tr(\n 'planmagnet.productFeatures.dialog.description',\n 'A feature is a capability the team decided to build. Customer asks stay feature requests — link them to the feature that answers them.'\n )}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-4\">\n <div>\n <label htmlFor={`${idPrefix}-name`} className=\"text-sm font-medium\">\n {tr('planmagnet.productFeatures.fields.name', 'Name')} *\n </label>\n <Input\n id={`${idPrefix}-name`}\n className=\"mt-1\"\n value={form.name}\n placeholder={tr(\n 'planmagnet.productFeatures.fields.namePlaceholder',\n 'e.g. Single sign-on'\n )}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n data-testid=\"product-feature-name\"\n />\n </div>\n <div>\n <label htmlFor={`${idPrefix}-description`} className=\"text-sm font-medium\">\n {tr('planmagnet.productFeatures.fields.description', 'Description')}\n </label>\n <textarea\n id={`${idPrefix}-description`}\n className={textareaClass}\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n data-testid=\"product-feature-description\"\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor={`${idPrefix}-status`} className=\"text-sm font-medium\">\n {tr('planmagnet.productFeatures.fields.status', 'Status')}\n </label>\n <select\n id={`${idPrefix}-status`}\n className={selectClass}\n value={form.status}\n onChange={(e) => setForm({ ...form, status: e.target.value })}\n data-testid=\"product-feature-status-select\"\n >\n {statuses.map((status) => (\n <option key={status} value={status}>\n {enumLabel(status)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor={`${idPrefix}-owner`} className=\"text-sm font-medium\">\n {tr('planmagnet.productFeatures.fields.owner', 'Owner')}\n </label>\n <div className=\"mt-1\">\n <AssigneeSelect\n id={`${idPrefix}-owner`}\n value={form.ownerId}\n noneLabel={tr('planmagnet.productFeatures.fields.noOwner', 'No owner')}\n onChange={(ownerId) => setForm({ ...form, ownerId })}\n />\n </div>\n </div>\n </div>\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void save()}\n disabled={!canSave}\n data-testid=\"product-feature-save\"\n >\n {saving\n ? tr('planmagnet.productFeatures.actions.saving', 'Saving…')\n : feature\n ? tr('planmagnet.productFeatures.actions.save', 'Save')\n : tr('planmagnet.productFeatures.actions.create', 'Create feature')}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── Archive / unarchive / delete (feature detail header) ───────────────────\n\nexport function ProductFeatureHeaderActions({\n feature,\n epicCount,\n requestCount,\n}: {\n feature: ProductFeatureValues;\n epicCount: number;\n requestCount: number;\n}) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const navigate = usePlanMagnetNavigate();\n const [archive, archiveState] = useMutation(ARCHIVE_PRODUCT_FEATURE, writeOptions);\n const [unarchive, unarchiveState] = useMutation(UNARCHIVE_PRODUCT_FEATURE, writeOptions);\n // Leaves the page: no refetch of this (deleted) feature on the way out — the product page fetches its list on\n // mount (see utils/mutationResult.ts).\n const [remove, removeState] = useMutation(DELETE_PRODUCT_FEATURE, {\n context: LEAVES_PAGE_CONTEXT,\n });\n const [error, setError] = useState<string | null>(null);\n const busy = archiveState.loading || unarchiveState.loading || removeState.loading;\n\n const onToggleArchive = async () => {\n setError(null);\n try {\n if (feature.archivedAt) await throwOnError(unarchive({ variables: { id: feature.id } }));\n else await throwOnError(archive({ variables: { id: feature.id } }));\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productFeatures.errors.update', 'The feature could not be updated.'),\n forbidden\n )\n );\n }\n };\n\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: feature.id } }));\n navigate(detailPath('/products/product-detail-page', feature.productId));\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productFeatures.errors.delete', 'The feature could not be deleted.'),\n forbidden\n )\n );\n }\n };\n\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex flex-wrap justify-end gap-2\">\n <ProductFeatureFormDialog productId={feature.productId} feature={feature} />\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={busy}\n onClick={() => void onToggleArchive()}\n data-testid=\"product-feature-toggle-archive\"\n >\n {feature.archivedAt ? (\n <ArchiveRestore className=\"mr-1 h-4 w-4\" />\n ) : (\n <Archive className=\"mr-1 h-4 w-4\" />\n )}\n {feature.archivedAt\n ? tr('planmagnet.productFeatures.actions.unarchive', 'Unarchive')\n : tr('planmagnet.productFeatures.actions.archive', 'Archive')}\n </Button>\n <ConfirmButton\n label={tr('planmagnet.productFeatures.actions.delete', 'Delete')}\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n testId=\"product-feature-delete\"\n title={tr('planmagnet.productFeatures.confirmDelete.title', 'Delete {{name}}?', {\n name: feature.name,\n })}\n description={tr(\n 'planmagnet.productFeatures.confirmDelete.description',\n 'Its {{requests}} feature request(s) and {{epics}} epic(s) are kept — only their links to this feature are removed, and stories stay under their epics. No request or work item is deleted or changed. This cannot be undone here.',\n { requests: requestCount, epics: epicCount }\n )}\n confirmLabel={tr('planmagnet.productFeatures.confirmDelete.confirm', 'Delete feature')}\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\n// ─── A product's features (product detail) ──────────────────────────────────\n\ninterface FeatureListItem extends ProductFeatureValues {\n epics: { id: string }[];\n featureRequests: { id: string }[];\n}\n\ninterface FeatureListData {\n planmagnetProductFeatures: {\n items: FeatureListItem[];\n pageInfo: { hasNextPage: boolean };\n totalCount: number;\n };\n}\n\n/** The product page's Features section: list with status, \"Show archived\", and \"New feature\". */\nexport function ProductFeaturesPanel({\n productId,\n productArchived,\n}: {\n productId: string;\n productArchived: boolean;\n}) {\n const tr = useTr();\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [showArchived, setShowArchived] = useState(false);\n const { data, previousData, loading, error } = useQuery<FeatureListData>(PRODUCT_FEATURES_LIST, {\n variables: {\n workspaceId: workspaceId ?? '',\n productId,\n // isActive omitted lists active and archived alike.\n filter: showArchived ? undefined : { isActive: true },\n },\n skip: !workspaceId || !productId,\n });\n // Keep the rows on screen while the toggle refetches, instead of blanking the section.\n const list = (data ?? previousData)?.planmagnetProductFeatures;\n const features = list?.items ?? [];\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-features\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.panel.subtitle',\n 'Capabilities the team decided to build. Each links the epics that deliver it and the feature requests it answers.'\n )}\n </p>\n <div className=\"flex items-center gap-2\">\n <Button\n size=\"sm\"\n variant={showArchived ? 'default' : 'outline'}\n aria-pressed={showArchived}\n onClick={() => setShowArchived((v) => !v)}\n data-testid=\"product-features-toggle-archived\"\n >\n <Archive className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productFeatures.panel.showArchived', 'Show archived')}\n </Button>\n <ProductFeatureFormDialog productId={productId} disabled={productArchived} />\n </div>\n </div>\n {productArchived && (\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.panel.productArchived',\n 'This product is archived — unarchive it to add features.'\n )}\n </p>\n )}\n {error && (\n <ErrorLine\n message={tr(\n 'planmagnet.productFeatures.errors.load',\n 'Features could not be loaded: {{message}}',\n { message: error.message }\n )}\n />\n )}\n {loading && !list && (\n <p className=\"text-sm text-muted-foreground\">\n {tr('planmagnet.productFeatures.loading', 'Loading features…')}\n </p>\n )}\n {list && features.length === 0 && (\n <p className=\"py-4 text-center text-sm text-muted-foreground\">\n {showArchived\n ? tr('planmagnet.productFeatures.panel.emptyAll', 'This product has no features yet.')\n : tr(\n 'planmagnet.productFeatures.panel.empty',\n 'No active features yet. Add the first capability this product will deliver.'\n )}\n </p>\n )}\n {features.length > 0 && (\n <ul className=\"space-y-1\">\n {features.map((feature) => (\n <li\n key={feature.id}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-md border p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"flex min-w-0 items-center gap-2 text-left font-medium hover:underline\"\n onClick={() =>\n navigate(detailPath('/products/product-feature-detail-page', feature.id))\n }\n >\n <Puzzle className=\"h-4 w-4 shrink-0 text-primary\" />\n <span className=\"truncate\">{feature.name}</span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.panel.counts',\n '{{epics}} epic(s) · {{requests}} request(s)',\n { epics: feature.epics.length, requests: feature.featureRequests.length }\n )}\n </span>\n {feature.archivedAt && (\n <Badge variant=\"outline\" className=\"text-xs\">\n {tr('planmagnet.productFeatures.archived', 'Archived')}\n </Badge>\n )}\n <ProductFeatureStatusBadge status={feature.status} />\n </div>\n </li>\n ))}\n </ul>\n )}\n {list?.pageInfo.hasNextPage && (\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.panel.truncated',\n 'Showing the first {{shown}} of {{total}} features.',\n { shown: features.length, total: list.totalCount }\n )}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAuDA,IAAM,IACJ,2FACI,IACJ,kGAEI,IAAe;CAAE,gBAAgB;CAAyB,qBAAqB;CAAM;AAE3F,SAAS,IAAmB;AAE1B,QADW,GAAO,CAEhB,+CACA,mDACD;;AAGH,SAAgB,EAA0B,EAAE,aAA8B;AACxE,QACE,kBAAC,GAAD;EACE,SAAS,EAA4B,EAAO;EAC5C,WAAU;EACV,eAAY;YAEX,EAAU,EAAO;EACZ,CAAA;;AAWZ,SAAgB,EAAyB,EACvC,cACA,YACA,cAAW,MAKV;CACD,IAAM,IAAK,GAAO,EACZ,IAAY,GAAkB,EAC9B,EAAE,mBAAgB,GAAe,EACjC,IAAU;EACd,MAAM,GAAS,QAAQ;EACvB,aAAa,GAAS,eAAe;EACrC,QAAQ,GAAS,UAAU;EAE3B,SAAS,IAAW,EAAQ,WAAW,KAAO,GAAa,MAAM;EAClE,EACK,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,CAAC,GAAM,KAAW,EAAS,EAAQ,EACnC,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAQ,KAAe,EAAY,GAAwB,EAAa,EACzE,CAAC,GAAQ,KAAe,EAAY,GAAwB,EAAa,EACzE,IAAS,EAAY,WAAW,EAAY,SAC5C,IAAU,EAAK,KAAK,MAAM,KAAK,MAAM,CAAC,GACtC,IAAW,IACb,wBAAwB,EAAQ,OAChC,uBAAuB,KAErB,IAA+B,EAA+C,SAClF,EAAK,OACN,GACG,IACA,CAAC,EAAK,QAAQ,GAAG,EAAyB,EAExC,IAAO,YAAY;AACvB,IAAS,KAAK;EACd,IAAM,IAAO;GACX,MAAM,EAAK,KAAK,MAAM;GACtB,aAAa,EAAc,EAAK,YAAY;GAC5C,QAAQ,EAAK;GACb,SAAS,EAAK,WAAW;GAC1B;AACD,MAAI;AACF,OAAI,GAAS;IAOX,IAAM,IAAQ,EANC;KACb,MAAM,EAAQ,KAAK,MAAM;KACzB,aAAa,EAAc,EAAQ,eAAe,GAAG;KACrD,QAAQ,EAAQ;KAChB,SAAS,EAAQ;KAClB,EACmC,EAAK;AACzC,IAAI,OAAO,KAAK,EAAM,CAAC,SAAS,KAC9B,MAAM,EAAa,EAAO,EAAE,WAAW;KAAE,IAAI,EAAQ;KAAI;KAAO,EAAE,CAAC,CAAC;SAGtE,OAAM,EACJ,EAAO,EACL,WAAW,EACT,OAAO;IACL;IACA,MAAM,EAAK;IACX,QAAQ,EAAK;IACb,GAAI,EAAK,cAAc,EAAE,aAAa,EAAK,aAAa,GAAG,EAAE;IAC7D,GAAI,EAAK,UAAU,EAAE,SAAS,EAAK,SAAS,GAAG,EAAE;IAClD,EACF,EACF,CAAC,CACH;AAEH,KAAQ,GAAM;WACP,GAAG;AACV,KACE,EACE,GACA,IACI,EAAG,0CAA0C,kCAAkC,GAC/E,EAAG,4CAA4C,oCAAoC,EACvF,EACD,CACF;;;AAIL,QACE,kBAAC,GAAD;EACQ;EACN,eAAe,MAAS;AAEtB,GADA,EAAQ,EAAK,EACT,IAAM,EAAQ,EAAQ,GACrB,EAAS,KAAK;;YALvB,CAQE,kBAAC,GAAD;GAAyB,SAAA;aACtB,IACC,kBAAC,GAAD;IAAQ,MAAK;IAAK,SAAQ;IAAU,eAAY;cAAhD,CACE,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA,EAClC,EAAG,2CAA2C,OAAO,CAC/C;QAET,kBAAC,GAAD;IAAQ,MAAK;IAAe;IAAU,eAAY;cAAlD,CACE,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAChC,EAAG,0CAA0C,cAAc,CACrD;;GAEa,CAAA,EAC1B,kBAAC,GAAD;GAAyB,WAAU;aAAnC;IACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACG,IACG,EAAG,+CAA+C,eAAe,GACjE,EAAG,8CAA8C,cAAc,EAC7C,CAAA,EACxB,kBAAC,GAAD,EAAA,UACG,EACC,iDACA,yIACD,EAC2B,CAAA,CACP,EAAA,CAAA;IACzB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAS,GAAG,EAAS;OAAQ,WAAU;iBAA9C,CACG,EAAG,0CAA0C,OAAO,EAAC,KAChD;UACR,kBAAC,GAAD;OACE,IAAI,GAAG,EAAS;OAChB,WAAU;OACV,OAAO,EAAK;OACZ,aAAa,EACX,qDACA,sBACD;OACD,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,MAAM,EAAE,OAAO;QAAO,CAAC;OAC3D,eAAY;OACZ,CAAA,CACE,EAAA,CAAA;MACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAS,GAAG,EAAS;OAAe,WAAU;iBAClD,EAAG,iDAAiD,cAAc;OAC7D,CAAA,EACR,kBAAC,YAAD;OACE,IAAI,GAAG,EAAS;OAChB,WAAW;OACX,OAAO,EAAK;OACZ,WAAW,MAAM,EAAQ;QAAE,GAAG;QAAM,aAAa,EAAE,OAAO;QAAO,CAAC;OAClE,eAAY;OACZ,CAAA,CACE,EAAA,CAAA;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,SAAS,GAAG,EAAS;QAAU,WAAU;kBAC7C,EAAG,4CAA4C,SAAS;QACnD,CAAA,EACR,kBAAC,UAAD;QACE,IAAI,GAAG,EAAS;QAChB,WAAW;QACX,OAAO,EAAK;QACZ,WAAW,MAAM,EAAQ;SAAE,GAAG;SAAM,QAAQ,EAAE,OAAO;SAAO,CAAC;QAC7D,eAAY;kBAEX,EAAS,KAAK,MACb,kBAAC,UAAD;SAAqB,OAAO;mBACzB,EAAU,EAAO;SACX,EAFI,EAEJ,CACT;QACK,CAAA,CACL,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,SAAS,GAAG,EAAS;QAAS,WAAU;kBAC5C,EAAG,2CAA2C,QAAQ;QACjD,CAAA,EACR,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD;SACE,IAAI,GAAG,EAAS;SAChB,OAAO,EAAK;SACZ,WAAW,EAAG,6CAA6C,WAAW;SACtE,WAAW,MAAY,EAAQ;UAAE,GAAG;UAAM;UAAS,CAAC;SACpD,CAAA;QACE,CAAA,CACF,EAAA,CAAA,CACF;;MACF;;IACL,KAAS,kBAAC,GAAD,EAAW,SAAS,GAAS,CAAA;IACvC,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;KACE,eAAe,KAAK,GAAM;KAC1B,UAAU,CAAC;KACX,eAAY;eAEX,IACG,EAAG,6CAA6C,UAAU,GAC1D,IACE,EAAG,2CAA2C,OAAO,GACrD,EAAG,6CAA6C,iBAAiB;KAChE,CAAA,EACc,CAAA;IACD;KACT;;;AAMvB,SAAgB,EAA4B,EAC1C,YACA,cACA,mBAKC;CACD,IAAM,IAAK,GAAO,EACZ,IAAY,GAAkB,EAC9B,IAAW,GAAuB,EAClC,CAAC,GAAS,KAAgB,EAAY,GAAyB,EAAa,EAC5E,CAAC,GAAW,KAAkB,EAAY,GAA2B,EAAa,EAGlF,CAAC,GAAQ,KAAe,EAAY,GAAwB,EAChE,SAAS,GACV,CAAC,EACI,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,IAAO,EAAa,WAAW,EAAe,WAAW,EAAY,SAErE,IAAkB,YAAY;AAClC,IAAS,KAAK;AACd,MAAI;AACF,GAAI,EAAQ,aAAY,MAAM,EAAa,EAAU,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC,CAAC,GACnF,MAAM,EAAa,EAAQ,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC,CAAC;WAC5D,GAAG;AACV,KACE,EACE,GACA,EAAG,4CAA4C,oCAAoC,EACnF,EACD,CACF;;IAIC,IAAW,YAAY;AAC3B,IAAS,KAAK;AACd,MAAI;AAEF,GADA,MAAM,EAAa,EAAO,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC,CAAC,EAC7D,EAAS,EAAW,iCAAiC,EAAQ,UAAU,CAAC;WACjE,GAAG;AACV,KACE,EACE,GACA,EAAG,4CAA4C,oCAAoC,EACnF,EACD,CACF;;;AAIL,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAA0B,WAAW,EAAQ;KAAoB;KAAW,CAAA;IAC5E,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,UAAU;KACV,eAAe,KAAK,GAAiB;KACrC,eAAY;eALd,CAOG,EAAQ,aACP,kBAAC,GAAD,EAAgB,WAAU,gBAAiB,CAAA,GAE3C,kBAAC,GAAD,EAAS,WAAU,gBAAiB,CAAA,EAErC,EAAQ,aACL,EAAG,gDAAgD,YAAY,GAC/D,EAAG,8CAA8C,UAAU,CACxD;;IACT,kBAAC,GAAD;KACE,OAAO,EAAG,6CAA6C,SAAS;KAChE,SAAQ;KACR,MAAM,kBAAC,GAAD,EAAQ,WAAU,gBAAiB,CAAA;KACzC,QAAO;KACP,OAAO,EAAG,kDAAkD,oBAAoB,EAC9E,MAAM,EAAQ,MACf,CAAC;KACF,aAAa,EACX,wDACA,qOACA;MAAE,UAAU;MAAc,OAAO;MAAW,CAC7C;KACD,cAAc,EAAG,oDAAoD,iBAAiB;KACtF,aAAA;KACA,UAAU;KACV,iBAAiB,KAAK,GAAU;KAChC,CAAA;IACE;MACL,KAAS,kBAAC,GAAD,EAAW,SAAS,GAAS,CAAA,CACnC;;;AAoBV,SAAgB,EAAqB,EACnC,cACA,sBAIC;CACD,IAAM,IAAK,GAAO,EACZ,EAAE,mBAAgB,GAAe,EACjC,IAAW,GAAuB,EAClC,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,EAAE,SAAM,iBAAc,YAAS,aAAU,EAA0B,GAAuB;EAC9F,WAAW;GACT,aAAa,KAAe;GAC5B;GAEA,QAAQ,IAAe,KAAA,IAAY,EAAE,UAAU,IAAM;GACtD;EACD,MAAM,CAAC,KAAe,CAAC;EACxB,CAAC,EAEI,KAAQ,KAAQ,IAAe,2BAC/B,IAAW,GAAM,SAAS,EAAE;AAElC,QACE,kBAAC,OAAD;EAAK,WAAU;EAAY,eAAY;YAAvC;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eACV,EACC,6CACA,oHACD;KACC,CAAA,EACJ,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,MAAK;MACL,SAAS,IAAe,YAAY;MACpC,gBAAc;MACd,eAAe,GAAiB,MAAM,CAAC,EAAE;MACzC,eAAY;gBALd,CAOE,kBAAC,GAAD,EAAS,WAAU,gBAAiB,CAAA,EACnC,EAAG,iDAAiD,gBAAgB,CAC9D;SACT,kBAAC,GAAD;MAAqC;MAAW,UAAU;MAAmB,CAAA,CACzE;OACF;;GACL,KACC,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,oDACA,2DACD;IACC,CAAA;GAEL,KACC,kBAAC,GAAD,EACE,SAAS,EACP,0CACA,6CACA,EAAE,SAAS,EAAM,SAAS,CAC3B,EACD,CAAA;GAEH,KAAW,CAAC,KACX,kBAAC,KAAD;IAAG,WAAU;cACV,EAAG,sCAAsC,oBAAoB;IAC5D,CAAA;GAEL,KAAQ,EAAS,WAAW,KAC3B,kBAAC,KAAD;IAAG,WAAU;cACV,IACG,EAAG,6CAA6C,oCAAoC,GACpF,EACE,0CACA,8EACD;IACH,CAAA;GAEL,EAAS,SAAS,KACjB,kBAAC,MAAD;IAAI,WAAU;cACX,EAAS,KAAK,MACb,kBAAC,MAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,UAAD;MACE,MAAK;MACL,WAAU;MACV,eACE,EAAS,EAAW,yCAAyC,EAAQ,GAAG,CAAC;gBAJ7E,CAOE,kBAAC,GAAD,EAAQ,WAAU,iCAAkC,CAAA,EACpD,kBAAC,QAAD;OAAM,WAAU;iBAAY,EAAQ;OAAY,CAAA,CACzC;SACT,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,QAAD;QAAM,WAAU;kBACb,EACC,2CACA,+CACA;SAAE,OAAO,EAAQ,MAAM;SAAQ,UAAU,EAAQ,gBAAgB;SAAQ,CAC1E;QACI,CAAA;OACN,EAAQ,cACP,kBAAC,GAAD;QAAO,SAAQ;QAAU,WAAU;kBAChC,EAAG,uCAAuC,WAAW;QAChD,CAAA;OAEV,kBAAC,GAAD,EAA2B,QAAQ,EAAQ,QAAU,CAAA;OACjD;QACH;OA5BE,EAAQ,GA4BV,CACL;IACC,CAAA;GAEN,GAAM,SAAS,eACd,kBAAC,KAAD;IAAG,WAAU;cACV,EACC,8CACA,sDACA;KAAE,OAAO,EAAS;KAAQ,OAAO,EAAK;KAAY,CACnD;IACC,CAAA;GAEF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductFeatureLinkCard.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/ProductFeatureLinkCard.tsx"],"names":[],"mappings":"AAuCA,wBAAgB,sBAAsB,CAAC,EAAE,gBAAgB,EAAE,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,2CAsQxF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductFeatureLinkCard.js","names":[],"sources":["../../../src/planmagnet/product/ProductFeatureLinkCard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Link2, Puzzle, X } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ErrorLine } from '../controls/ConfirmButton';\nimport { ProductSelect } from '../controls/Pickers';\nimport { throwOnError } from '../utils/mutationResult';\nimport { detailPath } from '../utils/rowNavigation';\nimport {\n FEATURE_REQUEST_FEATURE_OPTIONS,\n FEATURE_REQUEST_PRODUCT_FEATURE,\n LINK_FEATURE_REQUEST_TO_PRODUCT_FEATURE,\n PRODUCT_FEATURE_QUERIES,\n UNLINK_FEATURE_REQUEST_FROM_PRODUCT_FEATURE,\n} from './hierarchyOperations';\nimport { ProductFeatureStatusBadge } from './ProductFeatureControls';\nimport { refusalMessage } from './refusal';\n\n/**\n * A feature request's product feature (PRM-01): the capability the team is building that answers this request.\n * The request stays a request — linking never converts it, and never sets or changes its product. A request with a\n * product may only point at a feature of that product, so its features are the only ones offered; a request with\n * no product picks a product first, then one of its features. Linking a request that already points at a feature\n * moves it (a request points at one feature at most).\n */\n\ninterface LinkedFeature {\n id: string;\n name: string;\n status: string;\n archivedAt: string | null;\n product: { id: string; name: string } | null;\n}\n\nconst selectClass =\n 'w-full rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60';\n\nexport function ProductFeatureLinkCard({ featureRequestId }: { featureRequestId: string }) {\n const tr = useTr();\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [choosing, setChoosing] = useState(false);\n const [pickedProductId, setPickedProductId] = useState('');\n const [featureId, setFeatureId] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const current = useQuery<{\n planmagnetFeatureRequest: {\n id: string;\n productId: string | null;\n productFeature: LinkedFeature | null;\n } | null;\n }>(FEATURE_REQUEST_PRODUCT_FEATURE, {\n variables: { id: featureRequestId },\n skip: !featureRequestId,\n });\n const request = current.data?.planmagnetFeatureRequest ?? null;\n const linked = request?.productFeature ?? null;\n // A request with a product can only point at that product's features.\n const productId = request?.productId ?? pickedProductId;\n\n const options = useQuery<{\n planmagnetProductFeatures: {\n items: { id: string; name: string; status: string }[];\n totalCount: number;\n };\n }>(FEATURE_REQUEST_FEATURE_OPTIONS, {\n variables: { workspaceId: workspaceId ?? '', productId },\n skip: !choosing || !workspaceId || !productId,\n });\n const writeOptions = { refetchQueries: PRODUCT_FEATURE_QUERIES, awaitRefetchQueries: true };\n const [link, linkState] = useMutation(LINK_FEATURE_REQUEST_TO_PRODUCT_FEATURE, writeOptions);\n const [unlink, unlinkState] = useMutation(\n UNLINK_FEATURE_REQUEST_FROM_PRODUCT_FEATURE,\n writeOptions\n );\n const forbidden = tr(\n 'planmagnet.productFeatures.errors.forbiddenLinks',\n 'Your role cannot change what this feature is linked to.'\n );\n const featureOptions = (options.data?.planmagnetProductFeatures.items ?? []).filter(\n (f) => f.id !== linked?.id\n );\n\n const closeChooser = () => {\n setChoosing(false);\n setPickedProductId('');\n setFeatureId('');\n };\n\n const onLink = async () => {\n if (!featureId) return;\n setError(null);\n try {\n await throwOnError(link({ variables: { featureRequestId, productFeatureId: featureId } }));\n closeChooser();\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr(\n 'planmagnet.productFeatures.requestCard.errors.link',\n 'The request could not be linked to the feature.'\n ),\n forbidden\n )\n );\n }\n };\n\n const onUnlink = async () => {\n if (!linked) return;\n setError(null);\n try {\n await throwOnError(unlink({ variables: { featureRequestId, productFeatureId: linked.id } }));\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr(\n 'planmagnet.productFeatures.requestCard.errors.unlink',\n 'The request could not be unlinked from the feature.'\n ),\n forbidden\n )\n );\n }\n };\n\n return (\n <Card data-testid=\"feature-request-product-feature\">\n <CardHeader>\n <CardTitle>\n {tr('planmagnet.productFeatures.requestCard.title', 'Product feature')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3 text-sm\">\n {current.error && (\n <ErrorLine\n message={tr(\n 'planmagnet.productFeatures.requestCard.errors.load',\n 'The product feature could not be loaded: {{message}}',\n { message: current.error.message }\n )}\n />\n )}\n {current.loading && !current.data && (\n <p className=\"text-muted-foreground\">\n {tr('planmagnet.productFeatures.loading', 'Loading features…')}\n </p>\n )}\n {linked ? (\n <div className=\"flex items-start justify-between gap-2\">\n <button\n type=\"button\"\n className=\"min-w-0 text-left hover:underline\"\n onClick={() =>\n navigate(detailPath('/products/product-feature-detail-page', linked.id))\n }\n data-testid=\"feature-request-product-feature-link\"\n >\n <span className=\"flex items-center gap-2 font-medium\">\n <Puzzle className=\"h-4 w-4 shrink-0 text-primary\" />\n <span className=\"truncate\">{linked.name}</span>\n </span>\n {linked.product && (\n <span className=\"text-xs text-muted-foreground\">\n {tr('planmagnet.productFeatures.requestCard.inProduct', 'in {{name}}', {\n name: linked.product.name,\n })}\n </span>\n )}\n </button>\n <div className=\"flex shrink-0 items-center gap-2\">\n {linked.archivedAt && (\n <Badge variant=\"outline\" className=\"text-xs\">\n {tr('planmagnet.productFeatures.archived', 'Archived')}\n </Badge>\n )}\n <ProductFeatureStatusBadge status={linked.status} />\n <Button\n size=\"icon\"\n variant=\"ghost\"\n aria-label={tr(\n 'planmagnet.productFeatures.requestCard.unlink',\n 'Unlink the product feature'\n )}\n disabled={unlinkState.loading}\n onClick={() => void onUnlink()}\n data-testid=\"feature-request-product-feature-unlink\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n ) : (\n request &&\n !choosing && (\n <p className=\"text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.requestCard.none',\n 'Not linked to a product feature yet — link the feature that will answer this request.'\n )}\n </p>\n )\n )}\n {error && <ErrorLine message={error} />}\n {request && choosing && (\n <div className=\"space-y-2\">\n {request.productId === null && (\n <div className=\"space-y-1\">\n <label htmlFor=\"feature-request-pick-product\" className=\"text-xs font-medium\">\n {tr('planmagnet.productFeatures.requestCard.product', 'Product')}\n </label>\n <ProductSelect\n id=\"feature-request-pick-product\"\n value={pickedProductId}\n noneLabel={tr(\n 'planmagnet.productFeatures.requestCard.chooseProduct',\n 'Choose a product'\n )}\n onChange={(next) => {\n setPickedProductId(next);\n setFeatureId('');\n }}\n />\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.requestCard.noProductHint',\n 'This request has no product, so any product’s feature can answer it. Linking does not set its product.'\n )}\n </p>\n </div>\n )}\n <label htmlFor=\"feature-request-pick-feature\" className=\"text-xs font-medium\">\n {tr('planmagnet.productFeatures.requestCard.feature', 'Feature')}\n </label>\n <select\n id=\"feature-request-pick-feature\"\n className={selectClass}\n value={featureId}\n disabled={!productId}\n onChange={(e) => setFeatureId(e.target.value)}\n data-testid=\"feature-request-pick-feature\"\n >\n <option value=\"\">\n {options.loading && !options.data\n ? tr('planmagnet.productFeatures.loading', 'Loading features…')\n : tr('planmagnet.productFeatures.requestCard.chooseFeature', 'Choose a feature')}\n </option>\n {featureOptions.map((f) => (\n <option key={f.id} value={f.id}>\n {f.name}\n </option>\n ))}\n </select>\n {options.data && featureOptions.length === 0 && (\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productFeatures.requestCard.noFeatures',\n 'This product has no other active feature. Add one from the product’s page.'\n )}\n </p>\n )}\n {options.error && <ErrorLine message={options.error.message} />}\n <div className=\"flex justify-end gap-2\">\n <Button size=\"sm\" variant=\"ghost\" onClick={closeChooser}>\n {tr('planmagnet.productFeatures.actions.cancel', 'Cancel')}\n </Button>\n <Button\n size=\"sm\"\n disabled={!featureId || linkState.loading}\n onClick={() => void onLink()}\n data-testid=\"feature-request-product-feature-save\"\n >\n {tr('planmagnet.productFeatures.requestCard.link', 'Link')}\n </Button>\n </div>\n </div>\n )}\n {request && !choosing && (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setError(null);\n setChoosing(true);\n }}\n data-testid=\"feature-request-product-feature-choose\"\n >\n <Link2 className=\"mr-1 h-4 w-4\" />\n {linked\n ? tr('planmagnet.productFeatures.requestCard.change', 'Change feature')\n : tr('planmagnet.productFeatures.requestCard.choose', 'Link a feature')}\n </Button>\n )}\n </CardContent>\n </Card>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductLineControls.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/ProductLineControls.tsx"],"names":[],"mappings":"AAqCA;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAmBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,iBAAiB,CAAA;CAAE,2CAgK3E;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,SAAS,GACV,EAAE;IACD,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,2CA8FA;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC,2CA0FA;AAiMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,2CA6FrE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductLineControls.js","names":[],"sources":["../../../src/planmagnet/product/ProductLineControls.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Button,\n Checkbox,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Archive, ArchiveRestore, Pencil, Plus, Trash2, X } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ConfirmButton, ErrorLine } from '../controls/ConfirmButton';\nimport { AssigneeSelect } from '../controls/WorkItemControls';\nimport { throwOnError } from '../utils/mutationResult';\nimport { detailPath } from '../utils/rowNavigation';\nimport { changedFields, normalizeText } from './hierarchy';\nimport {\n ARCHIVE_PRODUCT_LINE,\n ASSIGN_PRODUCT_LINE,\n CREATE_PRODUCT_LINE,\n DELETE_PRODUCT_LINE,\n PRODUCT_LINE_ASSIGNMENT,\n PRODUCT_LINE_CANDIDATE_PRODUCTS,\n PRODUCT_LINE_OPTIONS,\n PRODUCT_LINE_QUERIES,\n UNARCHIVE_PRODUCT_LINE,\n UPDATE_PRODUCT_LINE,\n} from './hierarchyOperations';\nimport { refusalMessage } from './refusal';\n\n/**\n * Product line controls (PRM-01). A line groups products — one line, many products, a product in at most one line.\n * The line never owns its products: archiving keeps them in it (an archived line just accepts no new ones), and\n * deleting it only unassigns them. Nothing here ever deletes or changes a product beyond which line it is in.\n */\n\nexport interface ProductLineValues {\n id: string;\n name: string;\n description: string | null;\n ownerId: string | null;\n archivedAt: string | null;\n}\n\nexport interface ProductLineProductRef {\n id: string;\n name: string;\n archivedAt: string | null;\n}\n\nconst textareaClass =\n 'mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[72px]';\nconst selectClass =\n 'w-full rounded-md border border-input bg-background px-3 py-2 text-sm disabled:opacity-60';\n\nconst writeOptions = { refetchQueries: PRODUCT_LINE_QUERIES, awaitRefetchQueries: true };\n\nfunction useForbiddenText() {\n const tr = useTr();\n return tr(\n 'planmagnet.productLines.errors.forbidden',\n 'Your role cannot change product lines in this workspace.'\n );\n}\n\n// ─── Create / edit ──────────────────────────────────────────────────────────\n\n/**\n * Create a line (no `line`) or edit one. An edit sends only the fields that changed, and an emptied description or\n * a cleared owner is sent as null, which clears it.\n */\nexport function ProductLineFormDialog({ line }: { line?: ProductLineValues }) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const { currentUser } = usePlanMagnet();\n const initial = {\n name: line?.name ?? '',\n description: line?.description ?? '',\n // A new line is owned by whoever creates it unless they pick someone else (or nobody).\n ownerId: line ? (line.ownerId ?? '') : (currentUser?.id ?? ''),\n };\n const [open, setOpen] = useState(false);\n const [form, setForm] = useState(initial);\n const [error, setError] = useState<string | null>(null);\n const [create, createState] = useMutation(CREATE_PRODUCT_LINE, writeOptions);\n const [update, updateState] = useMutation(UPDATE_PRODUCT_LINE, writeOptions);\n const saving = createState.loading || updateState.loading;\n const canSave = form.name.trim() !== '' && !saving;\n const idPrefix = line ? `product-line-edit-${line.id}` : 'product-line-new';\n\n const save = async () => {\n setError(null);\n const next = {\n name: form.name.trim(),\n description: normalizeText(form.description),\n ownerId: form.ownerId || null,\n };\n try {\n if (line) {\n const before = {\n name: line.name.trim(),\n description: normalizeText(line.description ?? ''),\n ownerId: line.ownerId,\n };\n const input = changedFields(before, next);\n if (Object.keys(input).length > 0) {\n await throwOnError(update({ variables: { id: line.id, input } }));\n }\n } else {\n await throwOnError(\n create({\n variables: {\n input: {\n name: next.name,\n ...(next.description ? { description: next.description } : {}),\n ...(next.ownerId ? { ownerId: next.ownerId } : {}),\n },\n },\n })\n );\n }\n setOpen(false);\n } catch (e) {\n setError(\n refusalMessage(\n e,\n line\n ? tr('planmagnet.productLines.errors.save', 'The product line could not be saved.')\n : tr('planmagnet.productLines.errors.create', 'The product line could not be created.'),\n forbidden\n )\n );\n }\n };\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) setForm(initial);\n else setError(null);\n }}\n >\n <ResponsiveDialogTrigger asChild>\n {line ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n data-testid=\"product-line-edit\"\n aria-label={tr('planmagnet.productLines.actions.editNamed', 'Edit {{name}}', {\n name: line.name,\n })}\n >\n <Pencil className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productLines.actions.edit', 'Edit')}\n </Button>\n ) : (\n <Button size=\"sm\" data-testid=\"product-line-new\">\n <Plus className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productLines.actions.new', 'New product line')}\n </Button>\n )}\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {line\n ? tr('planmagnet.productLines.dialog.editTitle', 'Edit product line')\n : tr('planmagnet.productLines.dialog.newTitle', 'New product line')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {tr(\n 'planmagnet.productLines.dialog.description',\n 'A product line groups related products. A product belongs to at most one line.'\n )}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-4\">\n <div>\n <label htmlFor={`${idPrefix}-name`} className=\"text-sm font-medium\">\n {tr('planmagnet.productLines.fields.name', 'Name')} *\n </label>\n <Input\n id={`${idPrefix}-name`}\n className=\"mt-1\"\n value={form.name}\n placeholder={tr('planmagnet.productLines.fields.namePlaceholder', 'e.g. Mobile apps')}\n onChange={(e) => setForm({ ...form, name: e.target.value })}\n data-testid=\"product-line-name\"\n />\n </div>\n <div>\n <label htmlFor={`${idPrefix}-description`} className=\"text-sm font-medium\">\n {tr('planmagnet.productLines.fields.description', 'Description')}\n </label>\n <textarea\n id={`${idPrefix}-description`}\n className={textareaClass}\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n data-testid=\"product-line-description\"\n />\n </div>\n <div>\n <label htmlFor={`${idPrefix}-owner`} className=\"text-sm font-medium\">\n {tr('planmagnet.productLines.fields.owner', 'Owner')}\n </label>\n <div className=\"mt-1\">\n <AssigneeSelect\n id={`${idPrefix}-owner`}\n value={form.ownerId}\n noneLabel={tr('planmagnet.productLines.fields.noOwner', 'No owner')}\n onChange={(ownerId) => setForm({ ...form, ownerId })}\n />\n </div>\n </div>\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button onClick={() => void save()} disabled={!canSave} data-testid=\"product-line-save\">\n {saving\n ? tr('planmagnet.productLines.actions.saving', 'Saving…')\n : line\n ? tr('planmagnet.productLines.actions.save', 'Save')\n : tr('planmagnet.productLines.actions.create', 'Create product line')}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── Archive / unarchive / delete ───────────────────────────────────────────\n\n/**\n * Edit, archive/unarchive and delete for one line. `onArchived` / `onDeleted` run after the service accepted the\n * write — the list may have dropped this card by then (archived lines are hidden by default), so the page, not\n * the card, says what happened.\n */\nexport function ProductLineActions({\n line,\n productCount,\n onArchived,\n onDeleted,\n}: {\n line: ProductLineValues;\n productCount: number;\n onArchived?: (name: string) => void;\n onDeleted?: (name: string) => void;\n}) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const [archive, archiveState] = useMutation(ARCHIVE_PRODUCT_LINE, writeOptions);\n const [unarchive, unarchiveState] = useMutation(UNARCHIVE_PRODUCT_LINE, writeOptions);\n const [remove, removeState] = useMutation(DELETE_PRODUCT_LINE, writeOptions);\n const [error, setError] = useState<string | null>(null);\n const busy = archiveState.loading || unarchiveState.loading || removeState.loading;\n\n const onToggleArchive = async () => {\n setError(null);\n try {\n if (line.archivedAt) {\n await throwOnError(unarchive({ variables: { id: line.id } }));\n } else {\n await throwOnError(archive({ variables: { id: line.id } }));\n onArchived?.(line.name);\n }\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productLines.errors.update', 'The product line could not be updated.'),\n forbidden\n )\n );\n }\n };\n\n const onDelete = async () => {\n setError(null);\n try {\n await throwOnError(remove({ variables: { id: line.id } }));\n onDeleted?.(line.name);\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productLines.errors.delete', 'The product line could not be deleted.'),\n forbidden\n )\n );\n }\n };\n\n return (\n <div className=\"flex flex-col items-end gap-2\">\n <div className=\"flex flex-wrap justify-end gap-2\">\n <ProductLineFormDialog line={line} />\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={busy}\n onClick={() => void onToggleArchive()}\n data-testid=\"product-line-toggle-archive\"\n >\n {line.archivedAt ? (\n <ArchiveRestore className=\"mr-1 h-4 w-4\" />\n ) : (\n <Archive className=\"mr-1 h-4 w-4\" />\n )}\n {line.archivedAt\n ? tr('planmagnet.productLines.actions.unarchive', 'Unarchive')\n : tr('planmagnet.productLines.actions.archive', 'Archive')}\n </Button>\n <ConfirmButton\n label={tr('planmagnet.productLines.actions.delete', 'Delete')}\n variant=\"outline\"\n icon={<Trash2 className=\"mr-1 h-4 w-4\" />}\n testId=\"product-line-delete\"\n title={tr('planmagnet.productLines.confirmDelete.title', 'Delete {{name}}?', {\n name: line.name,\n })}\n description={\n productCount === 0\n ? tr(\n 'planmagnet.productLines.confirmDelete.empty',\n 'The line has no products. Nothing else changes. This cannot be undone here.'\n )\n : tr(\n 'planmagnet.productLines.confirmDelete.withProducts',\n 'Its {{count}} product(s) are kept — they are only taken out of this line and show under \"No product line\". Nothing else about them changes. This cannot be undone here.',\n { count: productCount }\n )\n }\n confirmLabel={tr('planmagnet.productLines.confirmDelete.confirm', 'Delete product line')}\n destructive\n disabled={busy}\n onConfirm={() => void onDelete()}\n />\n </div>\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\n// ─── The products in a line ─────────────────────────────────────────────────\n\n/**\n * The products in one line, each linking to its product page with a \"take out of this line\" control, and an \"Add\n * products\" dialog. Taking a product out only unassigns it; the product itself is untouched.\n */\nexport function ProductLineProducts({\n line,\n products,\n}: {\n line: ProductLineValues;\n products: ProductLineProductRef[];\n}) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const navigate = usePlanMagnetNavigate();\n const [assign, assignState] = useMutation(ASSIGN_PRODUCT_LINE, writeOptions);\n const [removingId, setRemovingId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const onRemove = async (productId: string) => {\n setError(null);\n setRemovingId(productId);\n try {\n await throwOnError(assign({ variables: { productId, productLineId: null } }));\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr(\n 'planmagnet.productLines.errors.unassign',\n 'The product could not be taken out of the line.'\n ),\n forbidden\n )\n );\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-2\" data-testid=\"product-line-products\">\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n {products.length === 1\n ? tr('planmagnet.productLines.products.one', '1 product')\n : tr('planmagnet.productLines.products.count', '{{count}} products', {\n count: products.length,\n })}\n </p>\n <AddProductsToLineDialog line={line} existingIds={products.map((p) => p.id)} />\n </div>\n {products.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'planmagnet.productLines.products.empty',\n 'No products in this line yet. Add some here, or pick this line on a product’s page.'\n )}\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {products.map((product) => (\n <li\n key={product.id}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-md border p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"min-w-0 truncate text-left hover:underline\"\n onClick={() => navigate(detailPath('/products/product-detail-page', product.id))}\n >\n {product.name}\n </button>\n <div className=\"flex shrink-0 items-center gap-2\">\n {product.archivedAt && (\n <Badge variant=\"outline\" className=\"text-xs\">\n {tr('planmagnet.productLines.archived', 'Archived')}\n </Badge>\n )}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={tr(\n 'planmagnet.productLines.products.removeNamed',\n 'Take {{name}} out of this line',\n { name: product.name }\n )}\n disabled={assignState.loading}\n onClick={() => void onRemove(product.id)}\n data-testid=\"product-line-product-remove\"\n >\n {removingId === product.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n {error && <ErrorLine message={error} />}\n </div>\n );\n}\n\ninterface CandidateProduct {\n id: string;\n name: string;\n archivedAt: string | null;\n productLine: { id: string; name: string } | null;\n}\n\n/** Pick products to put in this line. A product already in another line moves here (a product is in one line). */\nfunction AddProductsToLineDialog({\n line,\n existingIds,\n}: {\n line: ProductLineValues;\n existingIds: string[];\n}) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const { workspaceId } = usePlanMagnet();\n const [open, setOpen] = useState(false);\n const [selected, setSelected] = useState<Set<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n const {\n data,\n loading,\n error: loadError,\n } = useQuery<{\n planmagnetProducts: { items: CandidateProduct[]; totalCount: number };\n }>(PRODUCT_LINE_CANDIDATE_PRODUCTS, {\n variables: { workspaceId: workspaceId ?? '' },\n skip: !open || !workspaceId,\n });\n const [assign, assignState] = useMutation(ASSIGN_PRODUCT_LINE, writeOptions);\n const loaded = data?.planmagnetProducts.items ?? [];\n const candidates = loaded.filter((p) => !existingIds.includes(p.id));\n const total = data?.planmagnetProducts.totalCount ?? 0;\n\n const toggle = (id: string, checked: boolean) =>\n setSelected((prev) => {\n const next = new Set(prev);\n if (checked) next.add(id);\n else next.delete(id);\n return next;\n });\n\n const onAdd = async () => {\n setError(null);\n try {\n await Promise.all(\n [...selected].map((productId) =>\n throwOnError(assign({ variables: { productId, productLineId: line.id } }))\n )\n );\n setSelected(new Set());\n setOpen(false);\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productLines.errors.assign', 'The products could not be added.'),\n forbidden\n )\n );\n }\n };\n\n // An archived line accepts no new products (the service refuses it), so it offers none.\n if (line.archivedAt) {\n return (\n <span className=\"text-xs text-muted-foreground\">\n {tr('planmagnet.productLines.products.archivedNoAdd', 'Unarchive to add products')}\n </span>\n );\n }\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) {\n setSelected(new Set());\n setError(null);\n }\n }}\n >\n <ResponsiveDialogTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" data-testid=\"product-line-add-products\">\n <Plus className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productLines.products.add', 'Add products')}\n </Button>\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {tr('planmagnet.productLines.products.addTitle', 'Add products to {{name}}', {\n name: line.name,\n })}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {tr(\n 'planmagnet.productLines.products.addDescription',\n 'A product is in one line at most: picking one that is in another line moves it here. Nothing else about the product changes.'\n )}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div\n className=\"max-h-80 space-y-1 overflow-y-auto\"\n data-testid=\"product-line-add-candidates\"\n >\n {loading && !data && (\n <p className=\"py-4 text-center text-sm text-muted-foreground\">\n {tr('planmagnet.productLines.loading', 'Loading…')}\n </p>\n )}\n {loadError && <ErrorLine message={loadError.message} />}\n {data && candidates.length === 0 && (\n <p className=\"py-4 text-center text-sm text-muted-foreground\">\n {loaded.length === 0\n ? tr('planmagnet.productLines.products.noProducts', 'No products yet.')\n : tr(\n 'planmagnet.productLines.products.noCandidates',\n 'Every product is already in this line.'\n )}\n </p>\n )}\n {candidates.map((product) => {\n const inputId = `product-line-add-${line.id}-${product.id}`;\n return (\n <label\n key={product.id}\n htmlFor={inputId}\n className=\"flex cursor-pointer items-center gap-3 rounded-md border p-2 text-sm hover:bg-muted\"\n >\n <Checkbox\n id={inputId}\n checked={selected.has(product.id)}\n onCheckedChange={(checked) => toggle(product.id, checked === true)}\n />\n <span className=\"min-w-0 flex-1 truncate\">{product.name}</span>\n {product.archivedAt && (\n <Badge variant=\"outline\" className=\"shrink-0 text-xs\">\n {tr('planmagnet.productLines.archived', 'Archived')}\n </Badge>\n )}\n {product.productLine && (\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {tr('planmagnet.productLines.products.movesFrom', 'moves from {{name}}', {\n name: product.productLine.name,\n })}\n </span>\n )}\n </label>\n );\n })}\n {total > loaded.length && (\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productLines.products.truncated',\n 'Showing the first {{shown}} of {{total}} products — pick this line on a product’s own page for the rest.',\n { shown: loaded.length, total }\n )}\n </p>\n )}\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter>\n <Button\n onClick={() => void onAdd()}\n disabled={selected.size === 0 || assignState.loading}\n data-testid=\"product-line-add-confirm\"\n >\n {assignState.loading\n ? tr('planmagnet.productLines.actions.adding', 'Adding…')\n : tr('planmagnet.productLines.products.addCount', 'Add {{count}} product(s)', {\n count: selected.size,\n })}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ─── A product's line (product detail) ──────────────────────────────────────\n\ninterface LineAssignment {\n id: string;\n productLineId: string | null;\n productLine: { id: string; name: string; archivedAt: string | null } | null;\n}\n\n/**\n * The product page's product-line select: assigns on change, \"No product line\" unassigns. Only active lines are\n * offered (an archived line accepts no new products); the product's current line stays listed — marked archived\n * when it is — so the select never claims the product is somewhere it is not.\n */\nexport function ProductLinePicker({ productId }: { productId: string }) {\n const tr = useTr();\n const forbidden = useForbiddenText();\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const assignment = useQuery<{ planmagnetProduct: LineAssignment | null }>(\n PRODUCT_LINE_ASSIGNMENT,\n { variables: { productId }, skip: !productId }\n );\n const options = useQuery<{\n planmagnetProductLines: { items: { id: string; name: string }[]; totalCount: number };\n }>(PRODUCT_LINE_OPTIONS, { variables: { workspaceId: workspaceId ?? '' }, skip: !workspaceId });\n const [assign, assignState] = useMutation(ASSIGN_PRODUCT_LINE, writeOptions);\n const [error, setError] = useState<string | null>(null);\n\n const current = assignment.data?.planmagnetProduct?.productLine ?? null;\n const lines = options.data?.planmagnetProductLines.items ?? [];\n const currentListed = !!current && lines.some((l) => l.id === current.id);\n\n const onSelect = async (next: string) => {\n if (next === (current?.id ?? '')) return;\n setError(null);\n try {\n await throwOnError(assign({ variables: { productId, productLineId: next || null } }));\n } catch (e) {\n setError(\n refusalMessage(\n e,\n tr('planmagnet.productLines.errors.assignOne', 'The product line could not be changed.'),\n forbidden\n )\n );\n }\n };\n\n if (assignment.error) {\n return (\n <ErrorLine\n message={tr(\n 'planmagnet.productLines.errors.loadAssignment',\n 'The product line could not be loaded: {{message}}',\n { message: assignment.error.message }\n )}\n />\n );\n }\n\n return (\n <div className=\"space-y-2\" data-testid=\"product-line-picker\">\n {/* The card around the picker already titles it; the label stays for screen readers. */}\n <label htmlFor=\"product-line-select\" className=\"sr-only\">\n {tr('planmagnet.productLines.picker.label', 'Product line')}\n </label>\n <select\n id=\"product-line-select\"\n className={selectClass}\n value={current?.id ?? ''}\n disabled={assignState.loading || (assignment.loading && !assignment.data)}\n onChange={(e) => void onSelect(e.target.value)}\n >\n <option value=\"\">{tr('planmagnet.productLines.picker.none', 'No product line')}</option>\n {current && !currentListed && (\n <option value={current.id} disabled>\n {current.archivedAt\n ? tr('planmagnet.productLines.picker.archivedOption', '{{name}} (archived)', {\n name: current.name,\n })\n : current.name}\n </option>\n )}\n {lines.map((l) => (\n <option key={l.id} value={l.id}>\n {l.name}\n </option>\n ))}\n </select>\n {options.error && <ErrorLine message={options.error.message} />}\n {error && <ErrorLine message={error} />}\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productLines.picker.help',\n 'Only active lines are offered — an archived line takes no new products.'\n )}{' '}\n <button\n type=\"button\"\n className=\"text-primary hover:underline\"\n onClick={() => navigate('/products/product-lines-page')}\n >\n {tr('planmagnet.productLines.picker.manage', 'Manage product lines')}\n </button>\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductTeamsPanel.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/ProductTeamsPanel.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,2CAkKrE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductTeamsPanel.js","names":[],"sources":["../../../src/planmagnet/product/ProductTeamsPanel.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Users, X } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ErrorLine } from '../controls/ConfirmButton';\nimport { TeamSelect } from '../controls/Pickers';\nimport { throwOnError } from '../utils/mutationResult';\nimport { detailPath } from '../utils/rowNavigation';\nimport { LINK_PRODUCT_TEAM, PRODUCT_TEAMS, UNLINK_PRODUCT_TEAM } from './hierarchyOperations';\nimport { refusalMessage } from './refusal';\n\n/**\n * The teams that own, plan or report on a product (PRM-01, Product ↔ Team many-to-many). The link is a record of\n * responsibility only: the service writes the join row and nothing else — no role, no team membership, no project\n * link — so linking or unlinking a team never changes what anyone can see or do. The panel says so where the\n * decision is made.\n */\n\ninterface LinkedTeam {\n id: string;\n name: string;\n description: string | null;\n members: { id: string }[];\n}\n\nexport function ProductTeamsPanel({ productId }: { productId: string }) {\n const tr = useTr();\n const navigate = usePlanMagnetNavigate();\n const { data, loading, error } = useQuery<{\n planmagnetProduct: { id: string; archivedAt: string | null; teams: LinkedTeam[] } | null;\n }>(PRODUCT_TEAMS, { variables: { productId }, skip: !productId });\n const options = { refetchQueries: ['ProductTeams'], awaitRefetchQueries: true };\n const [link, linkState] = useMutation(LINK_PRODUCT_TEAM, options);\n const [unlink, unlinkState] = useMutation(UNLINK_PRODUCT_TEAM, options);\n const [teamId, setTeamId] = useState('');\n const [removingId, setRemovingId] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n const product = data?.planmagnetProduct ?? null;\n const teams = product?.teams ?? [];\n const archived = !!product?.archivedAt;\n const forbidden = tr(\n 'planmagnet.productTeams.errors.forbidden',\n 'Your role cannot change which teams a product has.'\n );\n\n const onLink = async () => {\n if (!teamId) return;\n setActionError(null);\n try {\n await throwOnError(link({ variables: { productId, teamId } }));\n setTeamId('');\n } catch (e) {\n setActionError(\n refusalMessage(\n e,\n tr('planmagnet.productTeams.errors.link', 'The team could not be linked.'),\n forbidden\n )\n );\n }\n };\n\n const onUnlink = async (id: string) => {\n setActionError(null);\n setRemovingId(id);\n try {\n await throwOnError(unlink({ variables: { productId, teamId: id } }));\n } catch (e) {\n setActionError(\n refusalMessage(\n e,\n tr('planmagnet.productTeams.errors.unlink', 'The team could not be unlinked.'),\n forbidden\n )\n );\n } finally {\n setRemovingId(null);\n }\n };\n\n return (\n <div className=\"space-y-3\" data-testid=\"product-teams\">\n <p className=\"text-sm text-muted-foreground\" data-testid=\"product-teams-access-note\">\n {tr(\n 'planmagnet.productTeams.accessNote',\n 'Teams that own, plan or report on this product. Linking or unlinking a team does not change anyone’s access — every member keeps exactly the access their own role gives them.'\n )}\n </p>\n {error && (\n <ErrorLine\n message={tr(\n 'planmagnet.productTeams.errors.load',\n 'Teams could not be loaded: {{message}}',\n {\n message: error.message,\n }\n )}\n />\n )}\n {loading && !data && (\n <p className=\"text-sm text-muted-foreground\">\n {tr('planmagnet.productTeams.loading', 'Loading teams…')}\n </p>\n )}\n {product && teams.length === 0 && (\n <p className=\"py-2 text-center text-sm text-muted-foreground\">\n {tr('planmagnet.productTeams.empty', 'No teams linked to this product yet.')}\n </p>\n )}\n {teams.length > 0 && (\n <ul className=\"space-y-1\">\n {teams.map((team) => (\n <li\n key={team.id}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-md border p-2 text-sm\"\n >\n <button\n type=\"button\"\n className=\"flex min-w-0 items-center gap-2 text-left hover:underline\"\n onClick={() => navigate(detailPath('/team/team-detail-page', team.id))}\n >\n <Users className=\"h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"truncate\">{team.name}</span>\n </button>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {team.members.length === 1\n ? tr('planmagnet.productTeams.members.one', '1 member')\n : tr('planmagnet.productTeams.members.count', '{{count}} members', {\n count: team.members.length,\n })}\n </span>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n aria-label={tr('planmagnet.productTeams.unlinkNamed', 'Unlink {{name}}', {\n name: team.name,\n })}\n disabled={unlinkState.loading}\n onClick={() => void onUnlink(team.id)}\n data-testid=\"product-team-unlink\"\n >\n {removingId === team.id ? '…' : <X className=\"h-4 w-4\" />}\n </Button>\n </div>\n </li>\n ))}\n </ul>\n )}\n {product && (\n <div className=\"flex items-start gap-2 border-t pt-2\">\n <div className=\"flex-1\">\n <label htmlFor={`product-add-team-${productId}`} className=\"sr-only\">\n {tr('planmagnet.productTeams.pickLabel', 'Team to link')}\n </label>\n <TeamSelect\n id={`product-add-team-${productId}`}\n value={teamId}\n onChange={setTeamId}\n noneLabel={tr('planmagnet.productTeams.pick', 'Choose a team')}\n exclude={teams.map((t) => t.id)}\n disabled={archived}\n />\n </div>\n <Button\n size=\"sm\"\n disabled={!teamId || archived || linkState.loading}\n onClick={() => void onLink()}\n data-testid=\"product-team-link\"\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n {tr('planmagnet.productTeams.link', 'Link team')}\n </Button>\n </div>\n )}\n {archived && (\n <p className=\"text-xs text-muted-foreground\">\n {tr(\n 'planmagnet.productTeams.archived',\n 'This product is archived — unarchive it to link more teams.'\n )}\n </p>\n )}\n {actionError && <ErrorLine message={actionError} />}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkItemProductFeatureChip.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/WorkItemProductFeatureChip.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,0BAA0B,CAAC,EAAE,UAAU,EAAE,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,kDAsChF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WorkItemProductFeatureChip.js","names":[],"sources":["../../../src/planmagnet/product/WorkItemProductFeatureChip.tsx"],"sourcesContent":["import { useQuery } from '@apollo/client/react';\nimport { Puzzle } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { WORK_ITEM_PRODUCT_FEATURE } from './hierarchyOperations';\n\n/**\n * The read-only \"Product feature\" chip on a work item's page (PRM-01). An EPIC shows the feature it is linked to; a\n * story (or any item filed under an epic) shows its epic's feature, since stories reach a feature through their\n * epic. Links are made from the feature's page. Its own query: a failure here hides the chip, never the task page.\n */\n\ninterface FeatureRef {\n id: string;\n name: string;\n}\n\nexport function WorkItemProductFeatureChip({ workItemId }: { workItemId: string }) {\n const tr = useTr();\n const navigate = usePlanMagnetNavigate();\n const { data } = useQuery<{\n planmagnetWorkItem: {\n id: string;\n type: string;\n productFeature: FeatureRef | null;\n parent: { id: string; key: string; type: string; productFeature: FeatureRef | null } | null;\n } | null;\n }>(WORK_ITEM_PRODUCT_FEATURE, { variables: { id: workItemId }, skip: !workItemId });\n\n const item = data?.planmagnetWorkItem;\n if (!item) return null;\n const own = item.productFeature;\n const viaEpic = !own && item.parent?.type === 'EPIC' ? item.parent.productFeature : null;\n const feature = own ?? viaEpic;\n if (!feature) return null;\n\n return (\n <button\n type=\"button\"\n className=\"mt-2 inline-flex max-w-full items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs hover:bg-muted\"\n onClick={() => navigate(detailPath('/products/product-feature-detail-page', feature.id))}\n data-testid=\"work-item-product-feature\"\n >\n <Puzzle className=\"h-3 w-3 shrink-0 text-primary\" />\n <span className=\"text-muted-foreground\">\n {tr('planmagnet.productFeatures.chip.label', 'Product feature')}\n </span>\n <span className=\"truncate font-medium\">{feature.name}</span>\n {viaEpic && item.parent && (\n <span className=\"shrink-0 text-muted-foreground\">\n {tr('planmagnet.productFeatures.chip.viaEpic', 'via {{key}}', { key: item.parent.key })}\n </span>\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;AAkBA,SAAgB,EAA2B,EAAE,iBAAsC;CACjF,IAAM,IAAK,GAAO,EACZ,IAAW,GAAuB,EAClC,EAAE,YAAS,EAOd,GAA2B;EAAE,WAAW,EAAE,IAAI,GAAY;EAAE,MAAM,CAAC;EAAY,CAAC,EAE7E,IAAO,GAAM;AACnB,KAAI,CAAC,EAAM,QAAO;CAClB,IAAM,IAAM,EAAK,gBACX,IAAU,CAAC,KAAO,EAAK,QAAQ,SAAS,SAAS,EAAK,OAAO,iBAAiB,MAC9E,IAAU,KAAO;AAGvB,QAFK,IAGH,kBAAC,UAAD;EACE,MAAK;EACL,WAAU;EACV,eAAe,EAAS,EAAW,yCAAyC,EAAQ,GAAG,CAAC;EACxF,eAAY;YAJd;GAME,kBAAC,GAAD,EAAQ,WAAU,iCAAkC,CAAA;GACpD,kBAAC,QAAD;IAAM,WAAU;cACb,EAAG,yCAAyC,kBAAkB;IAC1D,CAAA;GACP,kBAAC,QAAD;IAAM,WAAU;cAAwB,EAAQ;IAAY,CAAA;GAC3D,KAAW,EAAK,UACf,kBAAC,QAAD;IAAM,WAAU;cACb,EAAG,2CAA2C,eAAe,EAAE,KAAK,EAAK,OAAO,KAAK,CAAC;IAClF,CAAA;GAEF;MAnBU"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchy.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/hierarchy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchy.js","names":[],"sources":["../../../src/planmagnet/product/hierarchy.ts"],"sourcesContent":["/**\n * PRM-01 product hierarchy — the pure helpers behind the product line, product feature and hierarchy pages:\n * Product line > Product > Feature > Epic > Story. No React and no GraphQL here, so every rule is unit-tested\n * (tests/productHierarchy.test.ts).\n *\n * Vocabulary (owner decision, binding): a FEATURE REQUEST is customer/user feedback asking for something; a\n * FEATURE (`PlanmagnetProductFeature`) is a product capability the team decided to build. A request may point at\n * the feature that addresses it — it is never converted into one.\n */\n\n// ─── Feature status ─────────────────────────────────────────────────────────\n\n/** `PlanmagnetProductFeatureStatus`, in lifecycle order (the SDL lists it alphabetically). */\nexport const PRODUCT_FEATURE_STATUSES = [\n 'BACKLOG',\n 'DISCOVERY',\n 'PLANNING',\n 'IN_DEVELOPMENT',\n 'RELEASED',\n] as const;\nexport type ProductFeatureStatus = (typeof PRODUCT_FEATURE_STATUSES)[number];\n\nexport function isProductFeatureStatus(value: string): value is ProductFeatureStatus {\n return (PRODUCT_FEATURE_STATUSES as readonly string[]).includes(value);\n}\n\n/** The fe-libs Badge variant for a feature status — semantic tokens only, never a raw colour. */\nexport type FeatureStatusBadgeVariant = 'outline' | 'secondary' | 'info' | 'default' | 'success';\n\nconst STATUS_VARIANTS: Record<ProductFeatureStatus, FeatureStatusBadgeVariant> = {\n BACKLOG: 'outline',\n DISCOVERY: 'secondary',\n PLANNING: 'info',\n IN_DEVELOPMENT: 'default',\n RELEASED: 'success',\n};\n\n/** A status the API returns that this list does not know yet still renders, as a plain outline badge. */\nexport function productFeatureStatusVariant(status: string): FeatureStatusBadgeVariant {\n return isProductFeatureStatus(status) ? STATUS_VARIANTS[status] : 'outline';\n}\n\n// ─── Forms ──────────────────────────────────────────────────────────────────\n\n/** A text input's value as the API wants it: trimmed, and an emptied field is `null` (clears it). */\nexport function normalizeText(value: string): string | null {\n const trimmed = value.trim();\n return trimmed === '' ? null : trimmed;\n}\n\n/**\n * The entries of `next` whose value differs from `initial` — what an edit form sends. Forms here send only the\n * fields the person changed, so a save never rewrites a field someone else edited meanwhile. Values are compared\n * with `===`, so callers normalize both sides first (see `normalizeText`).\n */\nexport function changedFields<T extends Record<string, unknown>>(initial: T, next: T): Partial<T> {\n const out: Partial<T> = {};\n for (const key of Object.keys(next) as (keyof T)[]) {\n if (next[key] !== initial[key]) out[key] = next[key];\n }\n return out;\n}\n\n// ─── Dates ──────────────────────────────────────────────────────────────────\n\n/**\n * A server date as a `Date`, or null when there is none or it cannot be read. `DateTime` fields arrive as ISO\n * strings, but a date carried in a GraphQL `String` serializes as epoch milliseconds (\"1727740800000\"), so both\n * forms are accepted rather than rendering \"Invalid Date\".\n */\nexport function parseServerDate(value: string | null | undefined): Date | null {\n if (!value) return null;\n const date = /^-?\\d+$/.test(value.trim()) ? new Date(Number(value)) : new Date(value);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\n// ─── Feature requests → features ────────────────────────────────────────────\n\nexport interface RequestProductRef {\n id: string;\n productId: string | null;\n}\n\n/**\n * The service's rule (planmagnetLinkFeatureRequestToProductFeature): a request that has a product may only point\n * at a feature of that same product; a request with no product may point at any feature. The UI offers only what\n * the service accepts — and still shows the service's own reason if it refuses.\n */\nexport function canLinkRequestToFeature(\n request: { productId: string | null },\n feature: { productId: string }\n): boolean {\n return request.productId === null || request.productId === feature.productId;\n}\n\n/**\n * The requests a feature's \"Link a request\" picker offers: the feature's own product's requests first, then the\n * requests with no product, each once, minus the ones already linked to this feature and any the service would\n * refuse (another product's).\n */\nexport function linkableRequests<T extends RequestProductRef>(\n sameProduct: readonly T[],\n anyProduct: readonly T[],\n featureProductId: string,\n alreadyLinkedIds: readonly string[]\n): T[] {\n const seen = new Set<string>(alreadyLinkedIds);\n const out: T[] = [];\n for (const request of [...sameProduct, ...anyProduct]) {\n if (seen.has(request.id)) continue;\n if (!canLinkRequestToFeature(request, { productId: featureProductId })) continue;\n seen.add(request.id);\n out.push(request);\n }\n return out;\n}\n\n// ─── The hierarchy tree ─────────────────────────────────────────────────────\n\nexport interface HierarchyWorkItem {\n id: string;\n key: string;\n title: string;\n type: string;\n status: string;\n}\n\nexport interface HierarchyEpic extends HierarchyWorkItem {\n /** The epic's direct children (stories, and any task or bug filed straight under it). */\n children: readonly HierarchyWorkItem[];\n}\n\nexport interface HierarchyFeature {\n id: string;\n name: string;\n status: string;\n archivedAt: string | null;\n epics: readonly HierarchyEpic[];\n}\n\nexport interface HierarchyLineRef {\n id: string;\n name: string;\n archivedAt: string | null;\n}\n\nexport interface HierarchyProduct {\n id: string;\n name: string;\n lifecycleStage: string;\n archivedAt: string | null;\n /** Null when the product is in no line. Still returned while its line is archived. */\n productLine: HierarchyLineRef | null;\n features: readonly HierarchyFeature[];\n}\n\nexport interface HierarchyGroup {\n /** Null for the \"No product line\" group. */\n line: HierarchyLineRef | null;\n products: HierarchyProduct[];\n}\n\nconst collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });\n\nfunction sortBy<T>(items: readonly T[], label: (item: T) => string): T[] {\n // A copy: Apollo hands out frozen arrays, so sorting in place would throw.\n return [...items].sort((a, b) => collator.compare(label(a), label(b)));\n}\n\nfunction sortProduct(product: HierarchyProduct): HierarchyProduct {\n return {\n ...product,\n features: sortBy(product.features, (f) => f.name).map((feature) => ({\n ...feature,\n // An epic's children keep the service's order — their backlog rank (position), then age.\n epics: sortBy(feature.epics, (e) => e.key),\n })),\n };\n}\n\n/**\n * Groups products under their product lines: every loaded line appears (an empty one too, so a new line is\n * visible), lines by name, then the products in no line under a final \"No product line\" group (`line: null`),\n * present only when it has products. Grouping reads each product's own `productLine`, never the line list alone,\n * so a product whose line was left out of `lines` (an archived line while archived ones are hidden, or one past\n * the first page) still lands under its real line instead of being shown as unassigned. Lines, products and\n * features are sorted by name and epics by key, naturally (PM-2 before PM-10); an epic's stories keep their\n * backlog order. The input is never mutated.\n */\nexport function buildProductHierarchy(\n lines: readonly HierarchyLineRef[],\n products: readonly HierarchyProduct[]\n): HierarchyGroup[] {\n const byLine = new Map<string, HierarchyGroup>();\n for (const line of lines) byLine.set(line.id, { line, products: [] });\n const unassigned: HierarchyProduct[] = [];\n for (const product of products) {\n const line = product.productLine;\n if (!line) {\n unassigned.push(product);\n continue;\n }\n const group = byLine.get(line.id) ?? { line, products: [] };\n group.products.push(product);\n byLine.set(line.id, group);\n }\n const groups = sortBy([...byLine.values()], (g) => g.line?.name ?? '').map((group) => ({\n line: group.line,\n products: sortBy(group.products, (p) => p.name).map(sortProduct),\n }));\n if (unassigned.length > 0) {\n groups.push({ line: null, products: sortBy(unassigned, (p) => p.name).map(sortProduct) });\n }\n return groups;\n}\n\n/** Expand/collapse key of a tree node. The \"No product line\" group's key is `line:none`. */\nexport function lineKey(line: HierarchyLineRef | null): string {\n return line ? `line:${line.id}` : 'line:none';\n}\nexport const productKey = (id: string) => `product:${id}`;\nexport const featureKey = (id: string) => `feature:${id}`;\nexport const epicKey = (id: string) => `epic:${id}`;\n\n/** Every expandable node's key — what \"Expand all\" opens. */\nexport function allNodeKeys(groups: readonly HierarchyGroup[]): Set<string> {\n const keys = new Set<string>();\n for (const group of groups) {\n keys.add(lineKey(group.line));\n for (const product of group.products) {\n keys.add(productKey(product.id));\n for (const feature of product.features) {\n keys.add(featureKey(feature.id));\n for (const epic of feature.epics) keys.add(epicKey(epic.id));\n }\n }\n }\n return keys;\n}\n\nexport interface HierarchyTotals {\n lines: number;\n products: number;\n features: number;\n epics: number;\n children: number;\n}\n\n/** How many of each level the tree holds (the \"No product line\" group is not a line). */\nexport function hierarchyTotals(groups: readonly HierarchyGroup[]): HierarchyTotals {\n const totals: HierarchyTotals = { lines: 0, products: 0, features: 0, epics: 0, children: 0 };\n for (const group of groups) {\n if (group.line) totals.lines++;\n for (const product of group.products) {\n totals.products++;\n for (const feature of product.features) {\n totals.features++;\n for (const epic of feature.epics) {\n totals.epics++;\n totals.children += epic.children.length;\n }\n }\n }\n }\n return totals;\n}\n\nexport interface FilteredHierarchy {\n groups: HierarchyGroup[];\n /** Keys of the nodes to open so every match is visible — the ancestors of each match. */\n expand: Set<string>;\n}\n\n/**\n * Narrows the tree to what matches `query` (case-insensitive, anywhere in a line, product or feature name, or an\n * epic's or child's key or title). A node that matches keeps its whole subtree — searching a product shows all of\n * its features — and a node is kept with only its matching descendants when they match and it does not. A blank\n * query returns the tree unchanged and opens nothing.\n */\nexport function filterProductHierarchy(\n groups: readonly HierarchyGroup[],\n query: string\n): FilteredHierarchy {\n const needle = query.trim().toLocaleLowerCase();\n const expand = new Set<string>();\n if (!needle) return { groups: [...groups], expand };\n const hit = (...texts: string[]) => texts.some((t) => t.toLocaleLowerCase().includes(needle));\n\n const filterEpic = (epic: HierarchyEpic): HierarchyEpic | null => {\n if (hit(epic.key, epic.title)) return epic;\n const children = epic.children.filter((child) => hit(child.key, child.title));\n if (children.length === 0) return null;\n expand.add(epicKey(epic.id));\n return { ...epic, children };\n };\n const filterFeature = (feature: HierarchyFeature): HierarchyFeature | null => {\n if (hit(feature.name)) return feature;\n const epics = feature.epics.map(filterEpic).filter((e): e is HierarchyEpic => e !== null);\n if (epics.length === 0) return null;\n expand.add(featureKey(feature.id));\n return { ...feature, epics };\n };\n const filterProduct = (product: HierarchyProduct): HierarchyProduct | null => {\n if (hit(product.name)) return product;\n const features = product.features\n .map(filterFeature)\n .filter((f): f is HierarchyFeature => f !== null);\n if (features.length === 0) return null;\n expand.add(productKey(product.id));\n return { ...product, features };\n };\n\n const out: HierarchyGroup[] = [];\n for (const group of groups) {\n if (group.line && hit(group.line.name)) {\n out.push(group);\n continue;\n }\n const products = group.products\n .map(filterProduct)\n .filter((p): p is HierarchyProduct => p !== null);\n if (products.length === 0) continue;\n expand.add(lineKey(group.line));\n out.push({ line: group.line, products });\n }\n return { groups: out, expand };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchyOperations.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/hierarchyOperations.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,kBAAkB,gCAiB9B,CAAC;AAEF,eAAO,MAAM,oBAAoB,gCAchC,CAAC;AAEF,eAAO,MAAM,uBAAuB,gCAYnC,CAAC;AAEF,eAAO,MAAM,+BAA+B,gCAe3C,CAAC;AAEF,eAAO,MAAM,aAAa,gCAezB,CAAC;AAEF,eAAO,MAAM,qBAAqB,gCA2BjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAoClC,CAAC;AAEF,eAAO,MAAM,+BAA+B,gCAgB3C,CAAC;AAEF,eAAO,MAAM,kCAAkC,gCAyC9C,CAAC;AAEF,eAAO,MAAM,iBAAiB,gCA0D7B,CAAC;AAEF,eAAO,MAAM,+BAA+B,gCAiB3C,CAAC;AAEF,eAAO,MAAM,+BAA+B,gCAgB3C,CAAC;AAEF,eAAO,MAAM,yBAAyB,gCAoBrC,CAAC;AAIF,eAAO,MAAM,mBAAmB,gCAM/B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAM/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,gCAOhC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAOlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAI/B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAY/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,gCAM7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAI/B,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAMlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAMlC,CAAC;AAEF,eAAO,MAAM,uBAAuB,gCAOnC,CAAC;AAEF,eAAO,MAAM,yBAAyB,gCAOrC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAIlC,CAAC;AAEF,eAAO,MAAM,uCAAuC,gCASnD,CAAC;AAEF,eAAO,MAAM,2CAA2C,gCASvD,CAAC;AAEF,eAAO,MAAM,4BAA4B,gCASxC,CAAC;AAEF,eAAO,MAAM,gCAAgC,gCAO5C,CAAC;AAIF,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,UAMhC,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,UAOnC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchyOperations.js","names":[],"sources":["../../../src/planmagnet/product/hierarchyOperations.ts"],"sourcesContent":["import { gql } from '@apollo/client';\n\n/**\n * PRM-01 GraphQL documents — product lines, product↔team links, product features and their epic / feature\n * request links, and the hierarchy read. Every document here has a twin in\n * src/operations/wspace/planmagnet/{queries,mutations,fragments}/productHierarchy.graphql, which `bun run codegen`\n * validates against the planmagnet schema and CI's live-supergraph drift job validates against what production\n * serves. tests/productHierarchyOperations.test.ts fails when the two copies differ, so what the pages send is what\n * those gates checked.\n *\n * Each page section that reads a PRM-01 field has a query of its own rather than a field added to an existing\n * page query: a field the gateway does not serve fails the WHOLE query, so a shared query would blank the product\n * page instead of one card.\n */\n\nconst PRODUCT_LINE_FIELDS = `\n id\n name\n description\n ownerId\n archivedAt\n createdAt\n updatedAt\n`;\n\nconst PRODUCT_FEATURE_FIELDS = `\n id\n productId\n name\n description\n status\n ownerId\n archivedAt\n createdAt\n updatedAt\n`;\n\n// ─── Queries ────────────────────────────────────────────────────────────────\n\nexport const PRODUCT_LINES_PAGE = gql`\n query ProductLinesPage($workspaceId: ID!, $filter: PlanmagnetProductLineFilter) {\n planmagnetProductLines(workspaceId: $workspaceId, filter: $filter, pagination: { first: 100 }) {\n items {\n ${PRODUCT_LINE_FIELDS}\n products {\n id\n name\n archivedAt\n }\n }\n pageInfo {\n hasNextPage\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_LINE_OPTIONS = gql`\n query ProductLineOptions($workspaceId: ID!) {\n planmagnetProductLines(\n workspaceId: $workspaceId\n filter: { isActive: true }\n pagination: { first: 100 }\n ) {\n items {\n id\n name\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_LINE_ASSIGNMENT = gql`\n query ProductLineAssignment($productId: ID!) {\n planmagnetProduct(id: $productId) {\n id\n productLineId\n productLine {\n id\n name\n archivedAt\n }\n }\n }\n`;\n\nexport const PRODUCT_LINE_CANDIDATE_PRODUCTS = gql`\n query ProductLineCandidateProducts($workspaceId: ID!) {\n planmagnetProducts(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n archivedAt\n productLine {\n id\n name\n }\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_TEAMS = gql`\n query ProductTeams($productId: ID!) {\n planmagnetProduct(id: $productId) {\n id\n archivedAt\n teams {\n id\n name\n description\n members {\n id\n }\n }\n }\n }\n`;\n\nexport const PRODUCT_FEATURES_LIST = gql`\n query ProductFeaturesList(\n $workspaceId: ID!\n $productId: ID!\n $filter: PlanmagnetProductFeatureFilter\n ) {\n planmagnetProductFeatures(\n workspaceId: $workspaceId\n productId: $productId\n filter: $filter\n pagination: { first: 100 }\n ) {\n items {\n ${PRODUCT_FEATURE_FIELDS}\n epics {\n id\n }\n featureRequests {\n id\n }\n }\n pageInfo {\n hasNextPage\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_FEATURE_DETAIL = gql`\n query ProductFeatureDetail($id: ID!) {\n planmagnetProductFeature(id: $id) {\n ${PRODUCT_FEATURE_FIELDS}\n product {\n id\n name\n archivedAt\n productLine {\n id\n name\n }\n }\n epics {\n id\n key\n title\n type\n status\n children {\n id\n key\n title\n type\n status\n }\n }\n featureRequests {\n id\n title\n status\n voteCount\n productId\n }\n }\n }\n`;\n\nexport const PRODUCT_FEATURE_EPIC_CANDIDATES = gql`\n query ProductFeatureEpicCandidates($workspaceId: ID!, $filter: PlanmagnetWorkItemFilter) {\n planmagnetWorkItems(workspaceId: $workspaceId, filter: $filter, pagination: { first: 20 }) {\n items {\n id\n key\n title\n type\n productFeature {\n id\n name\n }\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_FEATURE_REQUEST_CANDIDATES = gql`\n query ProductFeatureRequestCandidates(\n $workspaceId: ID!\n $sameProduct: PlanmagnetFeatureRequestFilter!\n $anyProduct: PlanmagnetFeatureRequestFilter\n ) {\n sameProduct: planmagnetFeatureRequests(\n workspaceId: $workspaceId\n filter: $sameProduct\n pagination: { first: 50 }\n ) {\n items {\n id\n title\n status\n productId\n productFeature {\n id\n name\n }\n }\n totalCount\n }\n anyProduct: planmagnetFeatureRequests(\n workspaceId: $workspaceId\n filter: $anyProduct\n pagination: { first: 50 }\n ) {\n items {\n id\n title\n status\n productId\n productFeature {\n id\n name\n }\n }\n totalCount\n }\n }\n`;\n\nexport const PRODUCT_HIERARCHY = gql`\n query ProductHierarchy(\n $workspaceId: ID!\n $lineFilter: PlanmagnetProductLineFilter\n $productFilter: PlanmagnetProductFilter\n $includeArchivedFeatures: Boolean\n ) {\n planmagnetProductLines(\n workspaceId: $workspaceId\n filter: $lineFilter\n pagination: { first: 100 }\n ) {\n items {\n id\n name\n archivedAt\n }\n totalCount\n }\n planmagnetProducts(\n workspaceId: $workspaceId\n filter: $productFilter\n pagination: { first: 100 }\n ) {\n items {\n id\n name\n lifecycleStage\n archivedAt\n productLine {\n id\n name\n archivedAt\n }\n features(includeArchived: $includeArchivedFeatures) {\n id\n name\n status\n archivedAt\n epics {\n id\n key\n title\n type\n status\n children {\n id\n key\n title\n type\n status\n }\n }\n }\n }\n totalCount\n }\n }\n`;\n\nexport const FEATURE_REQUEST_PRODUCT_FEATURE = gql`\n query FeatureRequestProductFeature($id: ID!) {\n planmagnetFeatureRequest(id: $id) {\n id\n productId\n productFeature {\n id\n name\n status\n archivedAt\n product {\n id\n name\n }\n }\n }\n }\n`;\n\nexport const FEATURE_REQUEST_FEATURE_OPTIONS = gql`\n query FeatureRequestFeatureOptions($workspaceId: ID!, $productId: ID!) {\n planmagnetProductFeatures(\n workspaceId: $workspaceId\n productId: $productId\n filter: { isActive: true }\n pagination: { first: 100 }\n ) {\n items {\n id\n name\n status\n }\n totalCount\n }\n }\n`;\n\nexport const WORK_ITEM_PRODUCT_FEATURE = gql`\n query WorkItemProductFeature($id: ID!) {\n planmagnetWorkItem(id: $id) {\n id\n type\n productFeature {\n id\n name\n }\n parent {\n id\n key\n type\n productFeature {\n id\n name\n }\n }\n }\n }\n`;\n\n// ─── Mutations ──────────────────────────────────────────────────────────────\n\nexport const CREATE_PRODUCT_LINE = gql`\n mutation CreateProductLine($input: PlanmagnetCreateProductLineInput!) {\n planmagnetCreateProductLine(input: $input) {\n ${PRODUCT_LINE_FIELDS}\n }\n }\n`;\n\nexport const UPDATE_PRODUCT_LINE = gql`\n mutation UpdateProductLine($id: ID!, $input: PlanmagnetUpdateProductLineInput!) {\n planmagnetUpdateProductLine(id: $id, input: $input) {\n ${PRODUCT_LINE_FIELDS}\n }\n }\n`;\n\nexport const ARCHIVE_PRODUCT_LINE = gql`\n mutation ArchiveProductLine($id: ID!) {\n planmagnetArchiveProductLine(id: $id) {\n id\n archivedAt\n }\n }\n`;\n\nexport const UNARCHIVE_PRODUCT_LINE = gql`\n mutation UnarchiveProductLine($id: ID!) {\n planmagnetUnarchiveProductLine(id: $id) {\n id\n archivedAt\n }\n }\n`;\n\nexport const DELETE_PRODUCT_LINE = gql`\n mutation DeleteProductLine($id: ID!) {\n planmagnetDeleteProductLine(id: $id)\n }\n`;\n\nexport const ASSIGN_PRODUCT_LINE = gql`\n mutation AssignProductLine($productId: ID!, $productLineId: ID) {\n planmagnetAssignProductLine(productId: $productId, productLineId: $productLineId) {\n id\n productLineId\n productLine {\n id\n name\n archivedAt\n }\n }\n }\n`;\n\nexport const LINK_PRODUCT_TEAM = gql`\n mutation LinkProductTeam($productId: ID!, $teamId: ID!) {\n planmagnetLinkProductTeam(productId: $productId, teamId: $teamId) {\n id\n }\n }\n`;\n\nexport const UNLINK_PRODUCT_TEAM = gql`\n mutation UnlinkProductTeam($productId: ID!, $teamId: ID!) {\n planmagnetUnlinkProductTeam(productId: $productId, teamId: $teamId)\n }\n`;\n\nexport const CREATE_PRODUCT_FEATURE = gql`\n mutation CreateProductFeature($input: PlanmagnetCreateProductFeatureInput!) {\n planmagnetCreateProductFeature(input: $input) {\n ${PRODUCT_FEATURE_FIELDS}\n }\n }\n`;\n\nexport const UPDATE_PRODUCT_FEATURE = gql`\n mutation UpdateProductFeature($id: ID!, $input: PlanmagnetUpdateProductFeatureInput!) {\n planmagnetUpdateProductFeature(id: $id, input: $input) {\n ${PRODUCT_FEATURE_FIELDS}\n }\n }\n`;\n\nexport const ARCHIVE_PRODUCT_FEATURE = gql`\n mutation ArchiveProductFeature($id: ID!) {\n planmagnetArchiveProductFeature(id: $id) {\n id\n archivedAt\n }\n }\n`;\n\nexport const UNARCHIVE_PRODUCT_FEATURE = gql`\n mutation UnarchiveProductFeature($id: ID!) {\n planmagnetUnarchiveProductFeature(id: $id) {\n id\n archivedAt\n }\n }\n`;\n\nexport const DELETE_PRODUCT_FEATURE = gql`\n mutation DeleteProductFeature($id: ID!) {\n planmagnetDeleteProductFeature(id: $id)\n }\n`;\n\nexport const LINK_FEATURE_REQUEST_TO_PRODUCT_FEATURE = gql`\n mutation LinkFeatureRequestToProductFeature($featureRequestId: ID!, $productFeatureId: ID!) {\n planmagnetLinkFeatureRequestToProductFeature(\n featureRequestId: $featureRequestId\n productFeatureId: $productFeatureId\n ) {\n id\n }\n }\n`;\n\nexport const UNLINK_FEATURE_REQUEST_FROM_PRODUCT_FEATURE = gql`\n mutation UnlinkFeatureRequestFromProductFeature($featureRequestId: ID!, $productFeatureId: ID!) {\n planmagnetUnlinkFeatureRequestFromProductFeature(\n featureRequestId: $featureRequestId\n productFeatureId: $productFeatureId\n ) {\n id\n }\n }\n`;\n\nexport const LINK_EPIC_TO_PRODUCT_FEATURE = gql`\n mutation LinkEpicToProductFeature($productFeatureId: ID!, $workItemId: ID!) {\n planmagnetLinkEpicToProductFeature(\n productFeatureId: $productFeatureId\n workItemId: $workItemId\n ) {\n id\n }\n }\n`;\n\nexport const UNLINK_EPIC_FROM_PRODUCT_FEATURE = gql`\n mutation UnlinkEpicFromProductFeature($productFeatureId: ID!, $workItemId: ID!) {\n planmagnetUnlinkEpicFromProductFeature(\n productFeatureId: $productFeatureId\n workItemId: $workItemId\n )\n }\n`;\n\n// ─── Refetch groups ─────────────────────────────────────────────────────────\n\n/** Every query that shows a product line, or which line a product is in. */\nexport const PRODUCT_LINE_QUERIES = [\n 'ProductLinesPage',\n 'ProductLineOptions',\n 'ProductLineAssignment',\n 'ProductLineCandidateProducts',\n 'ProductHierarchy',\n];\n\n/** Every query that shows a product feature, its epics or its requests. */\nexport const PRODUCT_FEATURE_QUERIES = [\n 'ProductFeaturesList',\n 'ProductFeatureDetail',\n 'ProductHierarchy',\n 'FeatureRequestProductFeature',\n 'FeatureRequestFeatureOptions',\n 'WorkItemProductFeature',\n];\n"],"mappings":";;AAeA,IAAM,IAAsB,sFAUtB,IAAyB,6GAclB,IAAqB,CAAG;;;;UAI3B,EAAoB;;;;;;;;;;;;;GAejB,IAAuB,CAAG;;;;;;;;;;;;;;GAgB1B,IAA0B,CAAG;;;;;;;;;;;;GAc7B,IAAkC,CAAG;;;;;;;;;;;;;;;GAiBrC,IAAgB,CAAG;;;;;;;;;;;;;;;GAiBnB,IAAwB,CAAG;;;;;;;;;;;;;UAa9B,EAAuB;;;;;;;;;;;;;;GAgBpB,IAAyB,CAAG;;;QAGjC,EAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmClB,IAAkC,CAAG;;;;;;;;;;;;;;;;GAkBrC,IAAqC,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CxC,IAAoB,CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DvB,IAAkC,CAAG;;;;;;;;;;;;;;;;;GAmBrC,IAAkC,CAAG;;;;;;;;;;;;;;;;GAkBrC,IAA4B,CAAG;;;;;;;;;;;;;;;;;;;;GAwB/B,IAAsB,CAAG;;;QAG9B,EAAoB;;;GAKf,IAAsB,CAAG;;;QAG9B,EAAoB;;;GAKf,IAAuB,CAAG;;;;;;;GAS1B,IAAyB,CAAG;;;;;;;GAS5B,IAAsB,CAAG;;;;GAMzB,IAAsB,CAAG;;;;;;;;;;;;GAczB,IAAoB,CAAG;;;;;;GAQvB,IAAsB,CAAG;;;;GAMzB,IAAyB,CAAG;;;QAGjC,EAAuB;;;GAKlB,IAAyB,CAAG;;;QAGjC,EAAuB;;;GAKlB,IAA0B,CAAG;;;;;;;GAS7B,IAA4B,CAAG;;;;;;;GAS/B,IAAyB,CAAG;;;;GAM5B,IAA0C,CAAG;;;;;;;;;GAW7C,IAA8C,CAAG;;;;;;;;;GAWjD,IAA+B,CAAG;;;;;;;;;GAWlC,IAAmC,CAAG;;;;;;;GAYtC,IAAuB;CAClC;CACA;CACA;CACA;CACA;CACD,EAGY,IAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/refusal.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1F"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refusal.js","names":[],"sources":["../../../src/planmagnet/product/refusal.ts"],"sourcesContent":["import { CombinedGraphQLErrors } from '@apollo/client/errors';\nimport { isForbidden, mutationErrorMessage } from '../utils/graphqlErrors';\n\n/**\n * A refused PRM-01 write, in words. The gateway's role refusal (FORBIDDEN) reads as the plain `forbidden` sentence\n * the caller passes; anything else shows the service's own reason verbatim — a BAD_USER_INPUT such as \"That feature\n * request belongs to another product…\" is the actionable message, never paraphrased. Every PRM-01 operation sits on\n * the `planmagnet-product` RBAC resource, and, like the rest of the product pages, the controls stay visible: the\n * gateway decides, and the refusal says why.\n *\n * Verbatim means without `mutationErrorMessage`'s `field: ` prefix. The service tags several of these refusals with\n * `extensions.field` (featureRequestId, workItemId, name, status) and the public gateway forwards it, but every PRM-01\n * reason is already a whole sentence that says what was wrong, so the prefix would only put a raw input name in front\n * of it (\"featureRequestId: That feature request belongs to another product…\").\n */\nexport function refusalMessage(error: unknown, fallback: string, forbidden: string): string {\n if (isForbidden(error)) return forbidden;\n if (CombinedGraphQLErrors.is(error)) return error.errors[0]?.message || fallback;\n return mutationErrorMessage(error, fallback);\n}\n"],"mappings":";;;AAeA,SAAgB,EAAe,GAAgB,GAAkB,GAA2B;AAG1F,QAFI,EAAY,EAAM,GAAS,IAC3B,EAAsB,GAAG,EAAM,GAAS,EAAM,OAAO,IAAI,WAAW,IACjE,EAAqB,GAAO,EAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/product/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAElE,iHAAiH;AACjH,eAAO,MAAM,kBAAkB,gCAAgC,CAAC;AAEhE,wFAAwF;AACxF,eAAO,MAAM,sBAAsB,oCAAoC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,wCAAwC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","names":[],"sources":["../../../src/planmagnet/product/routes.ts"],"sourcesContent":["/**\n * Prioritization page route target (PRM-27), exported so the host shell can build a `NavItem` against the real,\n * routed path instead of a hand-typed string that can drift from `PlanMagnetRoutes.tsx` — same reasoning as\n * `integrations/routes.ts`. Relative, no leading slash — the same form `PlanMagnetRoot.tsx` passes through\n * `joinPath(basePath, ...)` for every other nav entry in this package, and the same form `path=\"…\"` carries in\n * `PlanMagnetRoutes.tsx`. This MFE also registers its own \"Products\" nav tree internally (PlanMagnetRoot.tsx),\n * so the export here is additionally consumed there.\n */\nexport const PRIORITIZATION_PATH = 'products/prioritization-page';\n\n/** Product lines page (PRM-01) — the top of the product hierarchy. Same relative form as PRIORITIZATION_PATH. */\nexport const PRODUCT_LINES_PATH = 'products/product-lines-page';\n\n/** Product hierarchy page (PRM-01): Product line > Product > Feature > Epic > Story. */\nexport const PRODUCT_HIERARCHY_PATH = 'products/product-hierarchy-page';\n\n/**\n * Customer satisfaction page (ANR-21): CSAT and NPS with their responses, add / edit / delete and the CSV import. It\n * takes `?window=&from=&to=&product=&release=&project=&metric=` so a product, release or delivery-KPI card can open it\n * already filtered (see satisfaction/satisfaction.ts `satisfactionPageLink`).\n */\nexport const CUSTOMER_SATISFACTION_PATH = 'products/customer-satisfaction-page';\n"],"mappings":";AAQA,IAAa,IAAsB,gCAGtB,IAAqB,+BAGrB,IAAyB,mCAOzB,IAA6B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PlanMagnetProvider.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/providers/PlanMagnetProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AASnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAoBpD;;GAEG;AACH,eAAO,MAAM,aAAa,2BAMzB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,eAKvB,MAAM,SAUhB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CA8HzE,CAAC"}
|