issue-sticker 0.2.2 → 0.3.1

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.
@@ -1,4 +1,4 @@
1
- import { q as gzip_1, r as record, a as cn, P as Primitive, l as useCallbackRef$1, j as useComposedRefs, h as Presence, n as Portal$1, g as composeEventHandlers, i as createContextScope, o as createSlot, D as DismissableLayer, C as Content, t as createPopperScope, e as useControllableState, v as Root2$1, f as useId, A as Anchor, w as Arrow, b as usePortalContainer, O as OVERLAY_LAYER, s as stopEscapePropagation, k as useLayoutEffect2, V as VISUALLY_HIDDEN_STYLES, c as createLucideIcon, x as clsx, S as Slot$2, d as OVERLAY_LAYER_INDEX } from "./createLucideIcon-B457EluY.js";
1
+ import { q as gzip_1, r as record, a as cn, P as Primitive, l as useCallbackRef$1, j as useComposedRefs, h as Presence, n as Portal$1, g as composeEventHandlers, i as createContextScope, o as createSlot, D as DismissableLayer, C as Content, t as createPopperScope, e as useControllableState, v as Root2$1, f as useId, A as Anchor, w as Arrow, b as usePortalContainer, d as OVERLAY_LAYER, s as stopEscapePropagation, k as useLayoutEffect2, V as VISUALLY_HIDDEN_STYLES, c as createLucideIcon, x as clsx, S as Slot$2, O as OVERLAY_LAYER_INDEX } from "./createLucideIcon-CmSNiW63.js";
2
2
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import React__default, { useState, createContext, useContext, useCallback, useRef, useLayoutEffect, useEffect, useMemo } from "react";
@@ -6084,6 +6084,25 @@ const ChevronRight = createLucideIcon("ChevronRight", [
6084
6084
  * See the LICENSE file in the root directory of this source tree.
6085
6085
  */
6086
6086
  const ChevronUp = createLucideIcon("ChevronUp", [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]]);
6087
+ /**
6088
+ * @license lucide-react v0.468.0 - ISC
6089
+ *
6090
+ * This source code is licensed under the ISC license.
6091
+ * See the LICENSE file in the root directory of this source tree.
6092
+ */
6093
+ const MousePointerClick = createLucideIcon("MousePointerClick", [
6094
+ ["path", { d: "M14 4.1 12 6", key: "ita8i4" }],
6095
+ ["path", { d: "m5.1 8-2.9-.8", key: "1go3kf" }],
6096
+ ["path", { d: "m6 12-1.9 2", key: "mnht97" }],
6097
+ ["path", { d: "M7.2 2.2 8 5.1", key: "1cfko1" }],
6098
+ [
6099
+ "path",
6100
+ {
6101
+ d: "M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z",
6102
+ key: "s0h3yz"
6103
+ }
6104
+ ]
6105
+ ]);
6087
6106
  /**
6088
6107
  * @license lucide-react v0.468.0 - ISC
6089
6108
  *
@@ -10768,14 +10787,17 @@ const POPOVER_FADE_MS = 180;
10768
10787
  const DEFAULT_LABELS = {
10769
10788
  badge: "가이드",
10770
10789
  close: "가이드 닫기",
10771
- skip: "스킵",
10790
+ skip: "건너뛰기",
10772
10791
  skipConfirmTitle: "가이드를 건너뛸까요?",
10773
- skipConfirmBody: "나중에 도움말이나 더보기 메뉴의 '가이드 다시 보기'에서 다시 열 수 있습니다.",
10792
+ // 표면마다 진입점이 다르다(admin=헤더 아이콘, extension=더보기 메뉴, sdk=FAB 메뉴).
10793
+ // 위치를 특정하면 어느 한쪽에서는 틀린 안내가 되므로 라벨만 가리킨다.
10794
+ skipConfirmBody: "'가이드 다시 보기'를 누르면 언제든 다시 열 수 있습니다.",
10774
10795
  skipConfirmCancel: "계속 보기",
10775
- skipConfirmConfirm: "스킵",
10796
+ skipConfirmConfirm: "건너뛰기",
10776
10797
  previous: "이전",
10777
10798
  next: "다음",
10778
- done: "완료"
10799
+ done: "완료",
10800
+ clickHint: "강조된 곳을 클릭하세요"
10779
10801
  };
10780
10802
  const MASK_PADDING = 8;
10781
10803
  const CUTOUT_RADIUS = 12;
@@ -10887,6 +10909,12 @@ function shouldRenderNextButton(step) {
10887
10909
  if (step.advanceOn && !step.allowManualAdvance) return false;
10888
10910
  return true;
10889
10911
  }
10912
+ function isTargetInteractionStep(step) {
10913
+ var _a;
10914
+ const hasTarget = !!step.targetId || (((_a = step.targetIds) == null ? void 0 : _a.length) ?? 0) > 0;
10915
+ if (!hasTarget) return false;
10916
+ return !!step.advanceOnTargetClick || !!step.advanceOn;
10917
+ }
10890
10918
  function OnboardingStyleTag() {
10891
10919
  return /* @__PURE__ */ jsx("style", { children: `
10892
10920
  .issue-sticker-onboarding-popover {
@@ -10897,11 +10925,16 @@ function OnboardingStyleTag() {
10897
10925
  .issue-sticker-onboarding-popover {
10898
10926
  transition-duration: 1ms !important;
10899
10927
  }
10928
+
10929
+ .issue-sticker-onboarding-highlight {
10930
+ animation: none !important;
10931
+ }
10900
10932
  }
10901
10933
  ` });
10902
10934
  }
10903
10935
  function OnboardingPopoverContent({
10904
10936
  step,
10937
+ clickHint,
10905
10938
  labels,
10906
10939
  canGoPrevious,
10907
10940
  isLast,
@@ -10967,6 +11000,10 @@ function OnboardingPopoverContent({
10967
11000
  return /* @__PURE__ */ jsxs("div", { children: [
10968
11001
  /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold leading-5 text-text-primary", children: step.title }),
10969
11002
  /* @__PURE__ */ jsx("p", { className: "mt-2 whitespace-pre-line text-sm leading-5 text-text-secondary", children: step.body }),
11003
+ clickHint ? /* @__PURE__ */ jsxs("p", { className: "mt-2 flex items-center gap-1.5 text-xs font-semibold leading-5 text-brand", children: [
11004
+ /* @__PURE__ */ jsx(MousePointerClick, { "aria-hidden": "true", className: "h-3.5 w-3.5 shrink-0" }),
11005
+ clickHint
11006
+ ] }) : null,
10970
11007
  /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center justify-between gap-2", children: [
10971
11008
  /* @__PURE__ */ jsx(
10972
11009
  "button",
@@ -11026,6 +11063,8 @@ function OnboardingOverlay({
11026
11063
  const shouldCenterPopover = !cutoutRect && (step.position ?? "center") === "center";
11027
11064
  const maskColor = "rgba(8, 13, 18, 0.62)";
11028
11065
  const isPassthrough = !!step.advanceOn;
11066
+ const isTargetInteraction = isTargetInteractionStep(step);
11067
+ const clickHint = isTargetInteraction ? step.clickHint ?? labels.clickHint : null;
11029
11068
  React.useEffect(() => {
11030
11069
  setIsSkipConfirmOpen(false);
11031
11070
  }, [step.id]);
@@ -11117,7 +11156,11 @@ function OnboardingOverlay({
11117
11156
  "div",
11118
11157
  {
11119
11158
  "aria-hidden": "true",
11120
- className: "fixed border border-white/90",
11159
+ "data-testid": "onboarding-cutout-outline",
11160
+ className: cn(
11161
+ "fixed",
11162
+ isTargetInteraction ? "issue-sticker-onboarding-highlight animate-pulse-ring border-2 border-brand" : "border border-white/90"
11163
+ ),
11121
11164
  style: {
11122
11165
  left: cutoutRect.left,
11123
11166
  top: cutoutRect.top,
@@ -11147,6 +11190,7 @@ function OnboardingOverlay({
11147
11190
  OnboardingPopoverContent,
11148
11191
  {
11149
11192
  step,
11193
+ clickHint,
11150
11194
  labels,
11151
11195
  canGoPrevious,
11152
11196
  isLast,
@@ -11381,7 +11425,7 @@ function OnboardingProvider({
11381
11425
  writeOnboardingStorage(storageInput, "completed");
11382
11426
  closeFlow();
11383
11427
  }, [closeFlow, storageInput]);
11384
- const dismiss = React.useCallback(() => {
11428
+ const dismiss2 = React.useCallback(() => {
11385
11429
  writeOnboardingStorage(storageInput, "dismissed");
11386
11430
  closeFlow();
11387
11431
  }, [closeFlow, storageInput]);
@@ -11467,7 +11511,7 @@ function OnboardingProvider({
11467
11511
  target: activeTarget,
11468
11512
  start,
11469
11513
  advance: advanceFromTargetClick,
11470
- dismiss,
11514
+ dismiss: dismiss2,
11471
11515
  complete
11472
11516
  });
11473
11517
  }, [
@@ -11476,7 +11520,7 @@ function OnboardingProvider({
11476
11520
  advanceFromTargetClick,
11477
11521
  complete,
11478
11522
  currentStepIndex,
11479
- dismiss,
11523
+ dismiss2,
11480
11524
  flowId,
11481
11525
  isOpen,
11482
11526
  start
@@ -11549,12 +11593,12 @@ function OnboardingProvider({
11549
11593
  registerTarget,
11550
11594
  start,
11551
11595
  advance: advanceFromTargetClick,
11552
- dismiss,
11596
+ dismiss: dismiss2,
11553
11597
  complete,
11554
11598
  isOpen,
11555
11599
  currentStep: isOpen ? activeStep : null
11556
11600
  }),
11557
- [activeStep, advanceFromTargetClick, complete, dismiss, isOpen, registerTarget, start]
11601
+ [activeStep, advanceFromTargetClick, complete, dismiss2, isOpen, registerTarget, start]
11558
11602
  );
11559
11603
  return /* @__PURE__ */ jsxs(OnboardingContext.Provider, { value: contextValue, children: [
11560
11604
  children,
@@ -11569,7 +11613,7 @@ function OnboardingProvider({
11569
11613
  isPopoverVisible,
11570
11614
  canGoPrevious: currentStepIndex > 0,
11571
11615
  isLast: currentStepIndex >= steps.length - 1,
11572
- onSkip: dismiss,
11616
+ onSkip: dismiss2,
11573
11617
  onNext: goNext,
11574
11618
  onPrevious: goPrevious
11575
11619
  }
@@ -11601,6 +11645,50 @@ function useOnboardingFlow() {
11601
11645
  [context]
11602
11646
  );
11603
11647
  }
11648
+ let nextId = 0;
11649
+ let toasts = [];
11650
+ const listeners = /* @__PURE__ */ new Set();
11651
+ function emit() {
11652
+ listeners.forEach((l2) => l2());
11653
+ }
11654
+ function addToast(message2, type, options) {
11655
+ const id = `toast-${++nextId}`;
11656
+ const t2 = {
11657
+ id,
11658
+ message: message2,
11659
+ type,
11660
+ action: options == null ? void 0 : options.action,
11661
+ duration: (options == null ? void 0 : options.duration) ?? 2e3,
11662
+ createdAt: Date.now()
11663
+ };
11664
+ toasts = [...toasts, t2];
11665
+ emit();
11666
+ return id;
11667
+ }
11668
+ function dismiss(id) {
11669
+ toasts = toasts.filter((t2) => t2.id !== id);
11670
+ emit();
11671
+ }
11672
+ function dismissAll() {
11673
+ toasts = [];
11674
+ emit();
11675
+ }
11676
+ function toast(message2, options) {
11677
+ return addToast(message2, "default", options);
11678
+ }
11679
+ toast.success = (message2, options) => addToast(message2, "success", options);
11680
+ toast.warning = (message2, options) => addToast(message2, "warning", options);
11681
+ toast.error = (message2, options) => addToast(message2, "error", options);
11682
+ toast.info = (message2, options) => addToast(message2, "info", options);
11683
+ toast.dismiss = dismiss;
11684
+ toast.dismissAll = dismissAll;
11685
+ function subscribe(listener) {
11686
+ listeners.add(listener);
11687
+ return () => listeners.delete(listener);
11688
+ }
11689
+ function getSnapshot() {
11690
+ return toasts;
11691
+ }
11604
11692
  ({
11605
11693
  type: [NetworkLogType.XMLHTTPREQUEST, NetworkLogType.FETCH]
11606
11694
  });
@@ -11695,6 +11783,11 @@ const devLogger = {
11695
11783
  write("debug", scope, args);
11696
11784
  }
11697
11785
  };
11786
+ function buildGuestOwnerQuery(mode, externalUserId) {
11787
+ if (mode !== "public") return "";
11788
+ if (!externalUserId) return "";
11789
+ return `?external_user_id=${encodeURIComponent(externalUserId)}`;
11790
+ }
11698
11791
  function extractDomain(url) {
11699
11792
  try {
11700
11793
  if (!url.includes("://")) {
@@ -12215,68 +12308,72 @@ function buildExternalUserPayload(user) {
12215
12308
  };
12216
12309
  }
12217
12310
  export {
12218
- hideOthers as $,
12219
- buildJiraIssueFields as A,
12220
- Button$1 as B,
12311
+ getPrimaryJiraMapping as $,
12312
+ getJiraMetadata as A,
12313
+ buildJiraIssueFields as B,
12221
12314
  ConsoleCollector as C,
12222
- ChevronDown as D,
12223
- Portal as E,
12224
- Content2 as F,
12225
- Check as G,
12226
- DatePicker as H,
12315
+ Button$1 as D,
12316
+ ChevronDown as E,
12317
+ Portal as F,
12318
+ Content2 as G,
12319
+ Check as H,
12227
12320
  Input as I,
12228
- getNotionPageMetadata as J,
12229
- buildNotionFieldViews as K,
12321
+ DatePicker as J,
12322
+ getNotionPageMetadata as K,
12230
12323
  Label as L,
12231
- DirectUploadError as M,
12324
+ buildNotionFieldViews as M,
12232
12325
  NetworkCollector as N,
12233
- getRegisteredUploadId as O,
12326
+ DirectUploadError as O,
12234
12327
  Popover as P,
12235
- getExposedJiraFields as Q,
12328
+ getRegisteredUploadId as Q,
12236
12329
  Root2 as R,
12237
12330
  ScreenRecordingController as S,
12238
12331
  Trigger as T,
12239
- isJiraFieldExposed as U,
12240
- getIntegrationFailureMessage as V,
12241
- getPrimaryJiraMapping as W,
12332
+ subscribe as U,
12333
+ getSnapshot as V,
12334
+ toast as W,
12242
12335
  X,
12243
- createCollection as Y,
12244
- useDirection as Z,
12245
- ReactRemoveScroll as _,
12336
+ getExposedJiraFields as Y,
12337
+ isJiraFieldExposed as Z,
12338
+ getIntegrationFailureMessage as _,
12246
12339
  uploadSignedMediaWithApi as a,
12247
- useFocusGuards as a0,
12248
- FocusScope as a1,
12249
- getPrimaryNotionMapping as a2,
12250
- buttonVariants as a3,
12251
- findElementBySelector as a4,
12252
- findElementByXPath as a5,
12253
- useOnboardingFlow as a6,
12254
- useOnboardingTarget as a7,
12255
- ONBOARDING_POPOVER_DATA_ATTR as a8,
12256
- OnboardingProvider as a9,
12340
+ createCollection as a0,
12341
+ useDirection as a1,
12342
+ ReactRemoveScroll as a2,
12343
+ hideOthers as a3,
12344
+ useFocusGuards as a4,
12345
+ FocusScope as a5,
12346
+ getPrimaryNotionMapping as a6,
12347
+ buttonVariants as a7,
12348
+ findElementBySelector as a8,
12349
+ findElementByXPath as a9,
12350
+ useOnboardingFlow as aa,
12351
+ useOnboardingTarget as ab,
12352
+ ONBOARDING_POPOVER_DATA_ATTR as ac,
12353
+ OnboardingProvider as ad,
12257
12354
  normalizeJiraFieldId as b,
12258
12355
  captureWithModernScreenshot as c,
12259
12356
  directUploadToSignedUrl as d,
12260
12357
  buildJiraCreateFields as e,
12261
12358
  buildNotionCreateFields as f,
12262
12359
  getElementPosition as g,
12263
- devLogger as h,
12264
- filterExcludeServiceRelatedLogs as i,
12265
- filterExcludeServiceRelatedConsoleLogs as j,
12266
- compactNetworkLogsForTransport as k,
12267
- sanitizeString as l,
12268
- buildExternalUserPayload as m,
12360
+ buildGuestOwnerQuery as h,
12361
+ devLogger as i,
12362
+ filterExcludeServiceRelatedLogs as j,
12363
+ filterExcludeServiceRelatedConsoleLogs as k,
12364
+ compactNetworkLogsForTransport as l,
12365
+ sanitizeString as m,
12269
12366
  normalizeExposedJiraFields as n,
12270
- SessionReplayCaptureController as o,
12271
- preloadModernScreenshot as p,
12272
- Select$1 as q,
12273
- SelectTrigger as r,
12367
+ buildExternalUserPayload as o,
12368
+ SessionReplayCaptureController as p,
12369
+ preloadModernScreenshot as q,
12370
+ Select$1 as r,
12274
12371
  syncExternalIssueIntegrations as s,
12275
- SelectValue as t,
12372
+ SelectTrigger as t,
12276
12373
  uploadScreenshotDataUrls as u,
12277
- SelectContent as v,
12278
- SelectItem as w,
12279
- PopoverTrigger as x,
12280
- PopoverContent as y,
12281
- getJiraMetadata as z
12374
+ SelectValue as v,
12375
+ SelectContent as w,
12376
+ SelectItem as x,
12377
+ PopoverTrigger as y,
12378
+ PopoverContent as z
12282
12379
  };
@@ -1,7 +1,7 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { memo, useRef, useState, useCallback, useEffect } from "react";
3
- import { c as createLucideIcon, u as ungzip_1, a as cn, R as Replayer } from "./createLucideIcon-B457EluY.js";
4
- import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-BkQcdrki.js";
3
+ import { c as createLucideIcon, u as ungzip_1, a as cn, R as Replayer } from "./createLucideIcon-CmSNiW63.js";
4
+ import { T as TooltipProvider, a as Tooltip, b as TooltipTrigger, c as TooltipContent } from "./tooltip-DciWyUWs.js";
5
5
  /**
6
6
  * @license lucide-react v0.468.0 - ISC
7
7
  *
@@ -1,7 +1,7 @@
1
- import { u as uploadScreenshotDataUrls, a as uploadSignedMediaWithApi, d as directUploadToSignedUrl, n as normalizeExposedJiraFields, b as normalizeJiraFieldId, g as getElementPosition, c as captureWithModernScreenshot, e as buildJiraCreateFields, f as buildNotionCreateFields, s as syncExternalIssueIntegrations, h as devLogger, C as ConsoleCollector, N as NetworkCollector, i as filterExcludeServiceRelatedLogs, j as filterExcludeServiceRelatedConsoleLogs, k as compactNetworkLogsForTransport, l as sanitizeString, m as buildExternalUserPayload, S as ScreenRecordingController, o as SessionReplayCaptureController, p as preloadModernScreenshot } from "./externalUserPayload-C2hxbvaU.js";
1
+ import { u as uploadScreenshotDataUrls, a as uploadSignedMediaWithApi, d as directUploadToSignedUrl, n as normalizeExposedJiraFields, b as normalizeJiraFieldId, g as getElementPosition, c as captureWithModernScreenshot, e as buildJiraCreateFields, f as buildNotionCreateFields, h as buildGuestOwnerQuery, s as syncExternalIssueIntegrations, i as devLogger, C as ConsoleCollector, N as NetworkCollector, j as filterExcludeServiceRelatedLogs, k as filterExcludeServiceRelatedConsoleLogs, l as compactNetworkLogsForTransport, m as sanitizeString, o as buildExternalUserPayload, S as ScreenRecordingController, p as SessionReplayCaptureController, q as preloadModernScreenshot } from "./externalUserPayload-hJjuUx6q.js";
2
2
  import "react/jsx-runtime";
3
3
  import "react";
4
- import "./createLucideIcon-B457EluY.js";
4
+ import "./createLucideIcon-CmSNiW63.js";
5
5
  class IssueStickerHeadlessError extends Error {
6
6
  constructor(code, message, cause) {
7
7
  super(message);
@@ -528,9 +528,8 @@ function upsertFilterGroup(groups, group) {
528
528
  options: mergeOptions(existing.options, group.options)
529
529
  });
530
530
  }
531
- function appendCustomFieldFilterGroups(groups, exposedFieldIds, customFields) {
531
+ function appendCustomFieldFilterGroups(groups, customFields) {
532
532
  for (const field of customFields) {
533
- if (!exposedFieldIds.has(normalizeJiraFieldId(field.field_key))) continue;
534
533
  const options = getSelectableCustomFieldOptions(field);
535
534
  if (!options.length) continue;
536
535
  upsertFilterGroup(groups, {
@@ -580,12 +579,15 @@ function composeIssueFilterGroups(integrations, customFields) {
580
579
  const config = getJiraConfig(integration);
581
580
  return integration.is_active !== false && config;
582
581
  });
582
+ appendCustomFieldFilterGroups(groups, customFields);
583
583
  const jiraConfig = jiraIntegration ? getJiraConfig(jiraIntegration) : null;
584
584
  const configExposedFields = getExposedFields(jiraConfig);
585
585
  if (configExposedFields.length) {
586
- const exposedFieldIds = new Set(configExposedFields);
587
- appendCustomFieldFilterGroups(groups, exposedFieldIds, customFields);
588
- appendJiraFieldFilterGroups(groups, exposedFieldIds, getLastKnownJiraFields(jiraConfig));
586
+ appendJiraFieldFilterGroups(
587
+ groups,
588
+ new Set(configExposedFields),
589
+ getLastKnownJiraFields(jiraConfig)
590
+ );
589
591
  }
590
592
  for (const integration of integrations) {
591
593
  if (integration.is_active === false) continue;
@@ -821,8 +823,12 @@ class HeadlessIssueRepository {
821
823
  return this.options.transport.requestResponse(endpoint, options);
822
824
  }
823
825
  openIssue(issueId) {
826
+ const ownerQuery = buildGuestOwnerQuery(
827
+ this.options.getAuthMode(),
828
+ this.options.getDefaultExternalUserId()
829
+ );
824
830
  return this.request(
825
- `/api/sdk/issues/${encodeURIComponent(issueId)}`
831
+ `/api/sdk/issues/${encodeURIComponent(issueId)}${ownerQuery}`
826
832
  );
827
833
  }
828
834
  createIssue(issueData) {
@@ -913,7 +919,7 @@ class HeadlessIssueRepository {
913
919
  },
914
920
  customFieldValues: customValues,
915
921
  upsertCustomFieldValue: (fieldDefinitionId, value) => this.request(
916
- `/api/custom-field-values/issues/${encodeURIComponent(createdIssue.id)}/values`,
922
+ `/api/sdk/custom-field-values/issues/${encodeURIComponent(createdIssue.id)}/values`,
917
923
  {
918
924
  method: "PUT",
919
925
  body: {