@aglyn/plugins-ai 1.0.0-beta.229 → 1.0.0-beta.230
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/README.md +3 -3
- package/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +7 -1
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-automation-zones.d.ts +38 -0
- package/src/lib/components/ai-automation-zones.js +5 -1
- package/src/lib/components/ai-automation-zones.js.map +1 -1
- package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
- package/src/lib/components/ai-brief-dialog.component.js +87 -8
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
- package/src/lib/components/ai-campaign-create.component.js +270 -0
- package/src/lib/components/ai-campaign-create.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
- package/src/lib/components/ai-describe-automation.component.js +15 -6
- package/src/lib/components/ai-describe-automation.component.js.map +1 -1
- package/src/lib/components/ai-describe-button.component.d.ts +20 -8
- package/src/lib/components/ai-describe-button.component.js +19 -36
- package/src/lib/components/ai-describe-button.component.js.map +1 -1
- package/src/lib/components/ai-describe-email.component.d.ts +31 -0
- package/src/lib/components/ai-describe-email.component.js +22 -0
- package/src/lib/components/ai-describe-email.component.js.map +1 -0
- package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
- package/src/lib/components/ai-describe-org-automation.component.js +238 -0
- package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
- package/src/lib/components/ai-experiment-cards.component.js +104 -18
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
- package/src/lib/components/ai-explain-automation.component.js +1 -5
- package/src/lib/components/ai-explain-automation.component.js.map +1 -1
- package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
- package/src/lib/components/ai-funnel-zones.component.js +178 -0
- package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
- package/src/lib/components/ai-insight-card.component.d.ts +42 -0
- package/src/lib/components/ai-insight-card.component.js +137 -0
- package/src/lib/components/ai-insight-card.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
- package/src/lib/components/ai-insight-dialog.component.js +9 -3
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.d.ts +7 -2
- package/src/lib/components/ai-job-plan.component.js +35 -5
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +17 -1
- package/src/lib/components/ai-job-requests.js +39 -3
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-logic-zones.d.ts +64 -0
- package/src/lib/components/ai-logic-zones.js +18 -0
- package/src/lib/components/ai-logic-zones.js.map +1 -0
- package/src/lib/components/ai-logic.component.d.ts +77 -0
- package/src/lib/components/ai-logic.component.js +553 -0
- package/src/lib/components/ai-logic.component.js.map +1 -0
- package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
- package/src/lib/components/ai-marketing-insight.component.js +80 -0
- package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
- package/src/lib/components/ai-media-create.component.d.ts +55 -0
- package/src/lib/components/ai-media-create.component.js +433 -0
- package/src/lib/components/ai-media-create.component.js.map +1 -0
- package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
- package/src/lib/components/ai-overlay-cards.component.js +505 -0
- package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
- package/src/lib/components/ai-product-zones.d.ts +5 -0
- package/src/lib/components/ai-product-zones.js +1 -1
- package/src/lib/components/ai-product-zones.js.map +1 -1
- package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
- package/src/lib/components/ai-products-create-button.component.js +67 -0
- package/src/lib/components/ai-products-create-button.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.js +100 -81
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
- package/src/lib/components/ai-revise-automation.component.js +207 -0
- package/src/lib/components/ai-revise-automation.component.js.map +1 -0
- package/src/lib/components/ai-site-build-page.component.js +140 -16
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
- package/src/lib/components/ai-upsell-dialog.component.js +177 -0
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
- package/src/lib/components/assist-build-card.component.d.ts +42 -0
- package/src/lib/components/assist-build-card.component.js +183 -0
- package/src/lib/components/assist-build-card.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +2 -0
- package/src/lib/components/assist-edit-canvas.js +56 -1
- package/src/lib/components/assist-edit-canvas.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.js +48 -3
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +51 -2
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/use-ai-job-run.d.ts +3 -14
- package/src/lib/components/use-ai-job-run.js +0 -50
- package/src/lib/components/use-ai-job-run.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
- package/src/lib/jobs/ai-build-capabilities.js +256 -0
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
- package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
- package/src/lib/jobs/ai-build-unit-outcome.js +138 -0
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
- package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
- package/src/lib/jobs/ai-job-build-step.js +657 -0
- package/src/lib/jobs/ai-job-build-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.js +9 -1
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
- package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
- package/src/lib/jobs/ai-job-drafts.js +25 -4
- package/src/lib/jobs/ai-job-drafts.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
- package/src/lib/jobs/ai-job-logic-step.js +395 -0
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
- package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
- package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
- package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
- package/src/lib/jobs/ai-job-page-step.js +6 -6
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +26 -1
- package/src/lib/jobs/ai-job-plan-step.js +79 -11
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +15 -1
- package/src/lib/jobs/ai-job-site-step.js +200 -58
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
- package/src/lib/jobs/ai-job-text-step.js +12 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
- package/src/lib/jobs/ai-job-workflow-step.js +318 -13
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +80 -2
- package/src/lib/jobs/ai-jobs.js +377 -13
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-logic-records.d.ts +40 -0
- package/src/lib/jobs/ai-logic-records.js +55 -0
- package/src/lib/jobs/ai-logic-records.js.map +1 -0
- package/src/lib/jobs/ai-site-publish.d.ts +7 -0
- package/src/lib/jobs/ai-site-publish.js +9 -0
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
- package/src/lib/jobs/ai-workflow-records.js +40 -1
- package/src/lib/jobs/ai-workflow-records.js.map +1 -1
- package/src/lib/model/ai-automation-draft.d.ts +18 -0
- package/src/lib/model/ai-automation-draft.js +86 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +201 -0
- package/src/lib/model/ai-build-job.js +471 -0
- package/src/lib/model/ai-build-job.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +61 -0
- package/src/lib/model/ai-build-plan.js +154 -9
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +56 -0
- package/src/lib/model/ai-build-progress.js +128 -0
- package/src/lib/model/ai-build-progress.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +20 -10
- package/src/lib/model/ai-insight.js +72 -9
- package/src/lib/model/ai-insight.js.map +1 -1
- package/src/lib/model/ai-job-activity.js +3 -1
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +80 -2
- package/src/lib/model/ai-jobs.types.js +3 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +108 -0
- package/src/lib/model/ai-logic-job.js +327 -0
- package/src/lib/model/ai-logic-job.js.map +1 -0
- package/src/lib/model/ai-media-credits.d.ts +52 -0
- package/src/lib/model/ai-media-credits.js +61 -0
- package/src/lib/model/ai-media-credits.js.map +1 -0
- package/src/lib/model/ai-overlay-copy.d.ts +114 -0
- package/src/lib/model/ai-overlay-copy.js +175 -0
- package/src/lib/model/ai-overlay-copy.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +20 -3
- package/src/lib/model/ai-site-build-progress.js +170 -10
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-svg.d.ts +69 -0
- package/src/lib/model/ai-svg.js +265 -0
- package/src/lib/model/ai-svg.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +3 -2
- package/src/lib/model/ai-usage-by-user.js.map +1 -1
- package/src/lib/model/ai-workflow-job.d.ts +92 -4
- package/src/lib/model/ai-workflow-job.js +124 -7
- package/src/lib/model/ai-workflow-job.js.map +1 -1
- package/src/lib/model/assist-build.d.ts +58 -0
- package/src/lib/model/assist-build.js +52 -0
- package/src/lib/model/assist-build.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +48 -3
- package/src/lib/model/assist-edit.js +48 -4
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +240 -11
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +81 -4
- package/src/lib/providers/catalog.js +80 -9
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +116 -0
- package/src/lib/providers/image-contract.js +74 -0
- package/src/lib/providers/image-contract.js.map +1 -0
- package/src/lib/providers/model-choice.js +11 -0
- package/src/lib/providers/model-choice.js.map +1 -1
- package/src/lib/providers/routing.js +18 -0
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/providers/vertex-image.d.ts +121 -0
- package/src/lib/providers/vertex-image.js +312 -0
- package/src/lib/providers/vertex-image.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +19 -0
- package/src/lib/runtime/ai-doctrine-validators.js +89 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +11 -5
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-eval-live.js +4 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -1
- package/src/lib/runtime/ai-eval.d.ts +15 -1
- package/src/lib/runtime/ai-eval.js +52 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
- package/src/lib/runtime/experiment-variant-copy.js +102 -0
- package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
- package/src/lib/server/ai-experiment-versions.d.ts +51 -0
- package/src/lib/server/ai-experiment-versions.js +270 -0
- package/src/lib/server/ai-experiment-versions.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.js +74 -4
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/server/ai-media-image.d.ts +66 -0
- package/src/lib/server/ai-media-image.js +521 -0
- package/src/lib/server/ai-media-image.js.map +1 -0
- package/src/lib/server/ai-media-svg.d.ts +91 -0
- package/src/lib/server/ai-media-svg.js +186 -0
- package/src/lib/server/ai-media-svg.js.map +1 -0
- package/src/lib/server/assist-build.d.ts +54 -0
- package/src/lib/server/assist-build.js +121 -0
- package/src/lib/server/assist-build.js.map +1 -0
- package/src/lib/server/assist-chat.js +108 -12
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.js +213 -3
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-view-context.js +242 -4
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +26 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tools/ai-logic-tool.d.ts +27 -0
- package/src/lib/tools/ai-logic-tool.js +207 -0
- package/src/lib/tools/ai-logic-tool.js.map +1 -0
- package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
- package/src/lib/tools/ai-overlay-tool.js +107 -0
- package/src/lib/tools/ai-overlay-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +11 -0
- package/src/lib/tools/ai-workflow-tool.js +31 -0
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
- package/src/lib/usage/assist-job-refund.d.ts +28 -1
- package/src/lib/usage/assist-job-refund.js +44 -9
- package/src/lib/usage/assist-job-refund.js.map +1 -1
- package/src/lib/usage/assist-usage.d.ts +5 -0
- package/src/lib/usage/assist-usage.js +2 -0
- package/src/lib/usage/assist-usage.js.map +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
18
|
+
import { mdiCreation } from "@aglyn/shared-data-mdi";
|
|
19
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
20
|
+
import { useConsoleHostRoute, useHostOrgId, useUser } from "@aglyn/tenant-feature-instance";
|
|
21
|
+
import { Button } from "@mui/material";
|
|
22
|
+
import { useState } from "react";
|
|
23
|
+
import { AiInsightDialog } from "./ai-insight-dialog.component.js";
|
|
24
|
+
import { AiUpsellButton } from "./ai-upsell-dialog.component.js";
|
|
25
|
+
/** What the button reads. */ export const AI_MARKETING_INSIGHT_LABEL = 'Ask AI about these numbers';
|
|
26
|
+
/** The question the dialog opens on, from what the report is about. */ export function aiMarketingInsightQuestion(subject, campaign) {
|
|
27
|
+
if (subject === 'campaign' && campaign) {
|
|
28
|
+
return `How did the campaign “${campaign}” do — what did it cause, and what did it earn?`;
|
|
29
|
+
}
|
|
30
|
+
return 'Which campaigns brought in the most conversions, and what did they earn?';
|
|
31
|
+
}
|
|
32
|
+
export function AiMarketingInsightButton(props) {
|
|
33
|
+
var _useHostOrgId, _ref;
|
|
34
|
+
const { hostId, subject, campaign } = props;
|
|
35
|
+
const { data: user } = useUser();
|
|
36
|
+
const orgId = (_useHostOrgId = useHostOrgId(hostId != null ? hostId : undefined)) != null ? _useHostOrgId : undefined;
|
|
37
|
+
const { orgSlug, subdomain } = useConsoleHostRoute(hostId);
|
|
38
|
+
const [open, setOpen] = useState(false);
|
|
39
|
+
// The figures are one site's: with no site there is nothing to read.
|
|
40
|
+
if (!hostId) return null;
|
|
41
|
+
// Drawn from the shell's gates alone (AGL-3601): nothing asks a server until
|
|
42
|
+
// it is used, and a plan without the add-on gets the add-on's dialog.
|
|
43
|
+
if (props.entitled === false) {
|
|
44
|
+
return props.upgrade ? /*#__PURE__*/ _jsx(AiUpsellButton, {
|
|
45
|
+
kind: "insight",
|
|
46
|
+
label: AI_MARKETING_INSIGHT_LABEL,
|
|
47
|
+
upgrade: props.upgrade
|
|
48
|
+
}) : null;
|
|
49
|
+
}
|
|
50
|
+
if (!orgId) return null;
|
|
51
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
54
|
+
size: "small",
|
|
55
|
+
variant: "outlined",
|
|
56
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
57
|
+
path: mdiCreation.path
|
|
58
|
+
}),
|
|
59
|
+
onClick: ()=>setOpen(true),
|
|
60
|
+
children: AI_MARKETING_INSIGHT_LABEL
|
|
61
|
+
}),
|
|
62
|
+
/*#__PURE__*/ _jsx(AiInsightDialog, {
|
|
63
|
+
open: open,
|
|
64
|
+
onClose: ()=>setOpen(false),
|
|
65
|
+
orgId: orgId,
|
|
66
|
+
orgSlug: orgSlug != null ? orgSlug : '',
|
|
67
|
+
hostId: hostId,
|
|
68
|
+
host: subdomain,
|
|
69
|
+
surface: "marketing",
|
|
70
|
+
user: user,
|
|
71
|
+
uid: (_ref = user == null ? void 0 : user.uid) != null ? _ref : null,
|
|
72
|
+
question: aiMarketingInsightQuestion(subject, campaign)
|
|
73
|
+
})
|
|
74
|
+
]
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
AiMarketingInsightButton.displayName = 'AiMarketingInsightButton';
|
|
78
|
+
export default AiMarketingInsightButton;
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=ai-marketing-insight.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-marketing-insight.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type { ConsoleWidgetEntitlementProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { useConsoleHostRoute, useHostOrgId, useUser } from '@aglyn/tenant-feature-instance'\nimport { Button } from '@mui/material'\nimport { useState } from 'react'\nimport { AiInsightDialog } from './ai-insight-dialog.component'\nimport { AiUpsellButton } from './ai-upsell-dialog.component'\n\n/**\n * \"Ask AI about these numbers\" (AGL-3603), in the header of the marketing\n * plugin's Conversions section and of one campaign's report, through the zone\n * that plugin hosts there.\n *\n * It opens the insight dialog the Assist panel opens, on the `marketing`\n * surface: the question starts an `insight` job, which reads the site's\n * figures through the readers the owning plugins publish — the campaigns, the\n * conversions they were credited with, the revenue they earned, the forms and\n * the traffic — and every insight it keeps cites the rows its numbers come\n * from. Nothing is changed or sent.\n *\n * The props restate the half of the zone's contract this widget reads.\n */\n\n/** What the `marketingInsights` zone hands this widget. */\nexport interface AiMarketingInsightButtonProps extends ConsoleWidgetEntitlementProps {\n hostId: string | null\n subject: 'conversions' | 'campaign'\n campaign: string | null\n}\n\n/** What the button reads. */\nexport const AI_MARKETING_INSIGHT_LABEL = 'Ask AI about these numbers'\n\n/** The question the dialog opens on, from what the report is about. */\nexport function aiMarketingInsightQuestion(\n subject: AiMarketingInsightButtonProps['subject'],\n campaign: string | null,\n): string {\n if (subject === 'campaign' && campaign) {\n return `How did the campaign “${campaign}” do — what did it cause, and what did it earn?`\n }\n return 'Which campaigns brought in the most conversions, and what did they earn?'\n}\n\nexport function AiMarketingInsightButton(props: AiMarketingInsightButtonProps) {\n const { hostId, subject, campaign } = props\n const { data: user } = useUser()\n const orgId = useHostOrgId(hostId ?? undefined) ?? undefined\n const { orgSlug, subdomain } = useConsoleHostRoute(hostId)\n const [open, setOpen] = useState(false)\n\n // The figures are one site's: with no site there is nothing to read.\n if (!hostId) return null\n // Drawn from the shell's gates alone (AGL-3601): nothing asks a server until\n // it is used, and a plan without the add-on gets the add-on's dialog.\n if (props.entitled === false) {\n return props.upgrade ? (\n <AiUpsellButton kind=\"insight\" label={AI_MARKETING_INSIGHT_LABEL} upgrade={props.upgrade} />\n ) : null\n }\n if (!orgId) return null\n\n return (\n <>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n onClick={() => setOpen(true)}\n >\n {AI_MARKETING_INSIGHT_LABEL}\n </Button>\n <AiInsightDialog\n open={open}\n onClose={() => setOpen(false)}\n orgId={orgId}\n orgSlug={orgSlug ?? ''}\n hostId={hostId}\n host={subdomain}\n surface=\"marketing\"\n user={user}\n uid={user?.uid ?? null}\n question={aiMarketingInsightQuestion(subject, campaign)}\n />\n </>\n )\n}\nAiMarketingInsightButton.displayName = 'AiMarketingInsightButton'\n\nexport default AiMarketingInsightButton\n"],"names":["mdiCreation","MdiIcon","useConsoleHostRoute","useHostOrgId","useUser","Button","useState","AiInsightDialog","AiUpsellButton","AI_MARKETING_INSIGHT_LABEL","aiMarketingInsightQuestion","subject","campaign","AiMarketingInsightButton","props","hostId","data","user","orgId","undefined","orgSlug","subdomain","open","setOpen","entitled","upgrade","kind","label","size","variant","startIcon","path","onClick","onClose","host","surface","uid","question","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAGA,SAASA,WAAW,QAAQ,yBAAwB;AACpD,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,mBAAmB,EAAEC,YAAY,EAAEC,OAAO,QAAQ,iCAAgC;AAC3F,SAASC,MAAM,QAAQ,gBAAe;AACtC,SAASC,QAAQ,QAAQ,QAAO;AAChC,SAASC,eAAe,QAAQ,mCAA+B;AAC/D,SAASC,cAAc,QAAQ,kCAA8B;AAwB7D,2BAA2B,GAC3B,OAAO,MAAMC,6BAA6B,6BAA4B;AAEtE,qEAAqE,GACrE,OAAO,SAASC,2BACdC,OAAiD,EACjDC,QAAuB;IAEvB,IAAID,YAAY,cAAcC,UAAU;QACtC,OAAO,CAAC,sBAAsB,EAAEA,SAAS,+CAA+C,CAAC;IAC3F;IACA,OAAO;AACT;AAEA,OAAO,SAASC,yBAAyBC,KAAoC;QAG7DX;IAFd,MAAM,EAAEY,MAAM,EAAEJ,OAAO,EAAEC,QAAQ,EAAE,GAAGE;IACtC,MAAM,EAAEE,MAAMC,IAAI,EAAE,GAAGb;IACvB,MAAMc,SAAQf,gBAAAA,aAAaY,iBAAAA,SAAUI,sBAAvBhB,gBAAqCgB;IACnD,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAE,GAAGnB,oBAAoBa;IACnD,MAAM,CAACO,MAAMC,QAAQ,GAAGjB,SAAS;IAEjC,qEAAqE;IACrE,IAAI,CAACS,QAAQ,OAAO;IACpB,6EAA6E;IAC7E,sEAAsE;IACtE,IAAID,MAAMU,QAAQ,KAAK,OAAO;QAC5B,OAAOV,MAAMW,OAAO,iBAClB,KAACjB;YAAekB,MAAK;YAAUC,OAAOlB;YAA4BgB,SAASX,MAAMW,OAAO;aACtF;IACN;IACA,IAAI,CAACP,OAAO,OAAO;IAEnB,qBACE;;0BACE,KAACb;gBACCuB,MAAK;gBACLC,SAAQ;gBACRC,yBAAW,KAAC7B;oBAAQ8B,MAAM/B,YAAY+B,IAAI;;gBAC1CC,SAAS,IAAMT,QAAQ;0BAEtBd;;0BAEH,KAACF;gBACCe,MAAMA;gBACNW,SAAS,IAAMV,QAAQ;gBACvBL,OAAOA;gBACPE,OAAO,EAAEA,kBAAAA,UAAW;gBACpBL,QAAQA;gBACRmB,MAAMb;gBACNc,SAAQ;gBACRlB,MAAMA;gBACNmB,GAAG,UAAEnB,wBAAAA,KAAMmB,GAAG,mBAAI;gBAClBC,UAAU3B,2BAA2BC,SAASC;;;;AAItD;AACAC,yBAAyByB,WAAW,GAAG;AAEvC,eAAezB,yBAAwB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { ConsoleMediaLibraryZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
|
|
18
|
+
import { type AiImageMode, type AiSvgStyle } from '../providers/image-contract';
|
|
19
|
+
/**
|
|
20
|
+
* "Create with AI" in Media (AGL-3602): pictures from a description, added to
|
|
21
|
+
* the library that is open, through the `mediaLibrary` zone beside Upload
|
|
22
|
+
* media and in the library's empty state.
|
|
23
|
+
*
|
|
24
|
+
* It draws from the shell's gates alone — the plan, the member's
|
|
25
|
+
* `ai.generate`, the plugin being on for the workspace and the site — and asks
|
|
26
|
+
* no server anything until someone creates a picture: the door decides then,
|
|
27
|
+
* and the dialog says what it decided. Two modes: an Illustration (an SVG the
|
|
28
|
+
* text AI draws, wherever text AI runs) and, where the deployment makes them,
|
|
29
|
+
* a Photo.
|
|
30
|
+
*/
|
|
31
|
+
/** Where the shell sends a reader to buy what the plan lacks (AGL-3601). */
|
|
32
|
+
export interface AiMediaUpgrade {
|
|
33
|
+
billingHref: string;
|
|
34
|
+
canManageBilling: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface AiMediaCreateButtonProps extends ConsoleMediaLibraryZoneProps {
|
|
37
|
+
/**
|
|
38
|
+
* `false` when the shell mounted this as its own upsell: the plan lacks AI
|
|
39
|
+
* generation and an add-on would grant it. Absent means entitled.
|
|
40
|
+
*/
|
|
41
|
+
entitled?: boolean;
|
|
42
|
+
upgrade?: AiMediaUpgrade;
|
|
43
|
+
}
|
|
44
|
+
/** The words each kind of illustration is offered in. */
|
|
45
|
+
export declare const AI_SVG_STYLE_LABELS: Record<AiSvgStyle, string>;
|
|
46
|
+
/** The sentence the estimate reads as, before anything is spent. */
|
|
47
|
+
export declare function aiMediaCreditEstimate(mode: AiImageMode, count: number): string;
|
|
48
|
+
export declare function AiMediaCreateButton(props: AiMediaCreateButtonProps): import("react").JSX.Element;
|
|
49
|
+
export interface AiMediaCreateDialogProps extends Pick<ConsoleMediaLibraryZoneProps, 'hostId' | 'library' | 'folderId' | 'onCreated'> {
|
|
50
|
+
open: boolean;
|
|
51
|
+
onClose: () => void;
|
|
52
|
+
orgId: string;
|
|
53
|
+
}
|
|
54
|
+
export declare function AiMediaCreateDialog({ open, onClose, orgId, hostId, library, folderId, onCreated, }: AiMediaCreateDialogProps): import("react").JSX.Element;
|
|
55
|
+
export default AiMediaCreateButton;
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Aglyn LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/ import { lockdownRefusalText, parseLockdownRefusal } from "@aglyn/aglyn";
|
|
19
|
+
import { mdiCreation } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
22
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
23
|
+
import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle, FormControlLabel, IconButton, LinearProgress, MenuItem, Radio, RadioGroup, Stack, TextField, ToggleButton, ToggleButtonGroup, Typography } from "@mui/material";
|
|
24
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
25
|
+
import { aiMediaCreditsPerPicture } from "../model/ai-media-credits.js";
|
|
26
|
+
import { AI_IMAGE_ASPECT_RATIOS, AI_IMAGE_MAX_COUNT, AI_IMAGE_PROMPT_MAX_CHARS, AI_SVG_MAX_COLORS, AI_SVG_STYLES, aiImagePhotosOffered } from "../providers/image-contract.js";
|
|
27
|
+
/** The words each shape is offered in. */ const ASPECT_LABELS = {
|
|
28
|
+
'1:1': 'Square',
|
|
29
|
+
'4:3': 'Landscape',
|
|
30
|
+
'3:4': 'Portrait',
|
|
31
|
+
'16:9': 'Wide',
|
|
32
|
+
'9:16': 'Tall'
|
|
33
|
+
};
|
|
34
|
+
/** The words each kind of illustration is offered in. */ export const AI_SVG_STYLE_LABELS = {
|
|
35
|
+
illustration: 'Illustration',
|
|
36
|
+
icon: 'Icon',
|
|
37
|
+
pattern: 'Pattern',
|
|
38
|
+
logo: 'Logo mark'
|
|
39
|
+
};
|
|
40
|
+
/** The sentence the estimate reads as, before anything is spent. */ export function aiMediaCreditEstimate(mode, count) {
|
|
41
|
+
const each = aiMediaCreditsPerPicture(mode);
|
|
42
|
+
const pictures = count === 1 ? '1 picture' : `${count} pictures`;
|
|
43
|
+
return `${pictures} uses about ${(count * each).toLocaleString()} AI credits ` + `(about ${each.toLocaleString()} each). A picture that is held back or does not come out is not charged.`;
|
|
44
|
+
}
|
|
45
|
+
export function AiMediaCreateButton(props) {
|
|
46
|
+
const { orgId, entitled, upgrade } = props;
|
|
47
|
+
const [open, setOpen] = useState(false);
|
|
48
|
+
if (!orgId) return null;
|
|
49
|
+
const button = /*#__PURE__*/ _jsx(Button, {
|
|
50
|
+
size: "small",
|
|
51
|
+
variant: "outlined",
|
|
52
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
53
|
+
path: mdiCreation.path
|
|
54
|
+
}),
|
|
55
|
+
onClick: ()=>setOpen(true),
|
|
56
|
+
children: 'Create with AI'
|
|
57
|
+
});
|
|
58
|
+
if (entitled === false) {
|
|
59
|
+
if (!upgrade) return null;
|
|
60
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
61
|
+
children: [
|
|
62
|
+
button,
|
|
63
|
+
/*#__PURE__*/ _jsxs(Dialog, {
|
|
64
|
+
open: open,
|
|
65
|
+
onClose: ()=>setOpen(false),
|
|
66
|
+
fullWidth: true,
|
|
67
|
+
maxWidth: "xs",
|
|
68
|
+
children: [
|
|
69
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
70
|
+
children: 'Create images with AI'
|
|
71
|
+
}),
|
|
72
|
+
/*#__PURE__*/ _jsx(DialogContent, {
|
|
73
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
74
|
+
children: upgrade.canManageBilling ? 'Creating pictures and illustrations comes with the AI add-on.' : 'Creating pictures and illustrations comes with the AI add-on. Ask an owner or admin of this workspace to add it.'
|
|
75
|
+
})
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
78
|
+
children: [
|
|
79
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
80
|
+
onClick: ()=>setOpen(false),
|
|
81
|
+
children: 'Close'
|
|
82
|
+
}),
|
|
83
|
+
upgrade.canManageBilling ? /*#__PURE__*/ _jsx(Button, {
|
|
84
|
+
variant: "contained",
|
|
85
|
+
href: upgrade.billingHref,
|
|
86
|
+
children: 'See the AI add-on'
|
|
87
|
+
}) : null
|
|
88
|
+
]
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
})
|
|
92
|
+
]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
96
|
+
children: [
|
|
97
|
+
button,
|
|
98
|
+
/*#__PURE__*/ _jsx(AiMediaCreateDialog, _extends({}, props, {
|
|
99
|
+
orgId: orgId,
|
|
100
|
+
open: open,
|
|
101
|
+
onClose: ()=>setOpen(false)
|
|
102
|
+
}))
|
|
103
|
+
]
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export function AiMediaCreateDialog({ open, onClose, orgId, hostId, library, folderId, onCreated }) {
|
|
107
|
+
const { data: user } = useUser();
|
|
108
|
+
const userRef = useRef(user);
|
|
109
|
+
userRef.current = user;
|
|
110
|
+
const photos = aiImagePhotosOffered();
|
|
111
|
+
const [mode, setMode] = useState(photos ? 'photo' : 'illustration');
|
|
112
|
+
const [style, setStyle] = useState('illustration');
|
|
113
|
+
// The site theme's colors need a site; the organization's library names none.
|
|
114
|
+
const [paletteSource, setPaletteSource] = useState(hostId ? 'theme' : 'custom');
|
|
115
|
+
const [colors, setColors] = useState([
|
|
116
|
+
'#1a73e8',
|
|
117
|
+
'#fbbc04'
|
|
118
|
+
]);
|
|
119
|
+
const [prompt, setPrompt] = useState('');
|
|
120
|
+
const [aspectRatio, setAspectRatio] = useState('1:1');
|
|
121
|
+
const [count, setCount] = useState(1);
|
|
122
|
+
const [busy, setBusy] = useState(false);
|
|
123
|
+
const [notice, setNotice] = useState(null);
|
|
124
|
+
useEffect(()=>{
|
|
125
|
+
if (open) setNotice(null);
|
|
126
|
+
}, [
|
|
127
|
+
open
|
|
128
|
+
]);
|
|
129
|
+
const create = useCallback(async ()=>{
|
|
130
|
+
const description = prompt.trim();
|
|
131
|
+
if (!description) return;
|
|
132
|
+
setBusy(true);
|
|
133
|
+
setNotice(null);
|
|
134
|
+
try {
|
|
135
|
+
var _ref, _ref1;
|
|
136
|
+
const response = await authorizedFetch(userRef.current, '/api/ai/media/images', {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers: {
|
|
139
|
+
'Content-Type': 'application/json'
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify(_extends({
|
|
142
|
+
orgId,
|
|
143
|
+
library,
|
|
144
|
+
hostId,
|
|
145
|
+
folderId,
|
|
146
|
+
mode,
|
|
147
|
+
prompt: description,
|
|
148
|
+
aspectRatio,
|
|
149
|
+
count
|
|
150
|
+
}, mode === 'illustration' ? {
|
|
151
|
+
style,
|
|
152
|
+
palette: paletteSource === 'theme' ? {
|
|
153
|
+
source: 'theme'
|
|
154
|
+
} : {
|
|
155
|
+
source: 'custom',
|
|
156
|
+
colors
|
|
157
|
+
}
|
|
158
|
+
} : {}))
|
|
159
|
+
});
|
|
160
|
+
const payload = await response.json().catch(()=>null);
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
var _ref2;
|
|
163
|
+
const locked = parseLockdownRefusal(response.status, payload);
|
|
164
|
+
setNotice({
|
|
165
|
+
severity: 'error',
|
|
166
|
+
text: locked ? lockdownRefusalText(locked) : String((_ref2 = payload == null ? void 0 : payload.error) != null ? _ref2 : 'The pictures could not be made — try again.')
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const ids = Array.isArray(payload == null ? void 0 : payload.mediaIds) ? payload.mediaIds : [];
|
|
171
|
+
onCreated(ids);
|
|
172
|
+
const missing = Number((_ref = payload == null ? void 0 : payload.filtered) != null ? _ref : 0) + Number((_ref1 = payload == null ? void 0 : payload.failed) != null ? _ref1 : 0);
|
|
173
|
+
if (missing > 0) {
|
|
174
|
+
setNotice({
|
|
175
|
+
severity: 'warning',
|
|
176
|
+
text: `Added ${ids.length} of ${count} to the library. ` + ((payload == null ? void 0 : payload.warning) ? String(payload.warning) : 'The rest were held back and were not charged.')
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
setPrompt('');
|
|
181
|
+
onClose();
|
|
182
|
+
} catch (unused) {
|
|
183
|
+
setNotice({
|
|
184
|
+
severity: 'error',
|
|
185
|
+
text: 'The pictures could not be made — try again.'
|
|
186
|
+
});
|
|
187
|
+
} finally{
|
|
188
|
+
setBusy(false);
|
|
189
|
+
}
|
|
190
|
+
}, [
|
|
191
|
+
prompt,
|
|
192
|
+
orgId,
|
|
193
|
+
library,
|
|
194
|
+
hostId,
|
|
195
|
+
folderId,
|
|
196
|
+
mode,
|
|
197
|
+
aspectRatio,
|
|
198
|
+
count,
|
|
199
|
+
style,
|
|
200
|
+
paletteSource,
|
|
201
|
+
colors,
|
|
202
|
+
onCreated,
|
|
203
|
+
onClose
|
|
204
|
+
]);
|
|
205
|
+
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
206
|
+
open: open,
|
|
207
|
+
onClose: busy ? undefined : onClose,
|
|
208
|
+
fullWidth: true,
|
|
209
|
+
maxWidth: "sm",
|
|
210
|
+
children: [
|
|
211
|
+
/*#__PURE__*/ _jsx(DialogTitle, {
|
|
212
|
+
children: 'Create images with AI'
|
|
213
|
+
}),
|
|
214
|
+
/*#__PURE__*/ _jsx(DialogContent, {
|
|
215
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
216
|
+
spacing: 2,
|
|
217
|
+
sx: {
|
|
218
|
+
pt: 1
|
|
219
|
+
},
|
|
220
|
+
children: [
|
|
221
|
+
photos ? /*#__PURE__*/ _jsxs(ToggleButtonGroup, {
|
|
222
|
+
size: "small",
|
|
223
|
+
exclusive: true,
|
|
224
|
+
value: mode,
|
|
225
|
+
onChange: (_event, next)=>{
|
|
226
|
+
if (next) setMode(next);
|
|
227
|
+
},
|
|
228
|
+
"aria-label": "What to make",
|
|
229
|
+
disabled: busy,
|
|
230
|
+
children: [
|
|
231
|
+
/*#__PURE__*/ _jsx(ToggleButton, {
|
|
232
|
+
value: "photo",
|
|
233
|
+
children: 'Photo'
|
|
234
|
+
}),
|
|
235
|
+
/*#__PURE__*/ _jsx(ToggleButton, {
|
|
236
|
+
value: "illustration",
|
|
237
|
+
children: 'Illustration or icon'
|
|
238
|
+
})
|
|
239
|
+
]
|
|
240
|
+
}) : null,
|
|
241
|
+
mode === 'illustration' ? /*#__PURE__*/ _jsx(TextField, {
|
|
242
|
+
select: true,
|
|
243
|
+
size: "small",
|
|
244
|
+
label: "Kind",
|
|
245
|
+
value: style,
|
|
246
|
+
onChange: (event)=>setStyle(event.target.value),
|
|
247
|
+
disabled: busy,
|
|
248
|
+
sx: {
|
|
249
|
+
maxWidth: 240
|
|
250
|
+
},
|
|
251
|
+
helperText: style === 'logo' ? 'A simple symbol, without lettering. Not a real brand’s logo.' : style === 'pattern' ? 'A seamless background that tiles.' : 'Drawn as an SVG, sharp at any size.',
|
|
252
|
+
children: AI_SVG_STYLES.map((value)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
253
|
+
value: value,
|
|
254
|
+
children: AI_SVG_STYLE_LABELS[value]
|
|
255
|
+
}, value))
|
|
256
|
+
}) : null,
|
|
257
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
258
|
+
label: mode === 'photo' ? 'Describe the picture' : 'Describe what to draw',
|
|
259
|
+
placeholder: mode === 'photo' ? 'A sunlit bakery counter with fresh sourdough loaves, warm morning light' : 'A friendly delivery van with a parcel, simple and flat',
|
|
260
|
+
value: prompt,
|
|
261
|
+
onChange: (event)=>setPrompt(event.target.value.slice(0, AI_IMAGE_PROMPT_MAX_CHARS)),
|
|
262
|
+
multiline: true,
|
|
263
|
+
minRows: 3,
|
|
264
|
+
autoFocus: true,
|
|
265
|
+
disabled: busy,
|
|
266
|
+
helperText: "The description becomes each picture's alt text, which you can edit."
|
|
267
|
+
}),
|
|
268
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
269
|
+
spacing: 0.5,
|
|
270
|
+
children: [
|
|
271
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
272
|
+
variant: "body2",
|
|
273
|
+
color: "text.secondary",
|
|
274
|
+
children: 'Shape'
|
|
275
|
+
}),
|
|
276
|
+
/*#__PURE__*/ _jsx(ToggleButtonGroup, {
|
|
277
|
+
size: "small",
|
|
278
|
+
exclusive: true,
|
|
279
|
+
value: aspectRatio,
|
|
280
|
+
onChange: (_event, next)=>{
|
|
281
|
+
if (next) setAspectRatio(next);
|
|
282
|
+
},
|
|
283
|
+
"aria-label": "Shape",
|
|
284
|
+
disabled: busy,
|
|
285
|
+
sx: {
|
|
286
|
+
flexWrap: 'wrap'
|
|
287
|
+
},
|
|
288
|
+
children: AI_IMAGE_ASPECT_RATIOS.map((ratio)=>/*#__PURE__*/ _jsx(ToggleButton, {
|
|
289
|
+
value: ratio,
|
|
290
|
+
"aria-label": `${ASPECT_LABELS[ratio]} ${ratio}`,
|
|
291
|
+
children: `${ASPECT_LABELS[ratio]} ${ratio}`
|
|
292
|
+
}, ratio))
|
|
293
|
+
})
|
|
294
|
+
]
|
|
295
|
+
}),
|
|
296
|
+
mode === 'illustration' ? /*#__PURE__*/ _jsxs(Stack, {
|
|
297
|
+
spacing: 1,
|
|
298
|
+
children: [
|
|
299
|
+
/*#__PURE__*/ _jsxs(RadioGroup, {
|
|
300
|
+
value: paletteSource,
|
|
301
|
+
onChange: (event)=>setPaletteSource(event.target.value),
|
|
302
|
+
"aria-label": "Colors",
|
|
303
|
+
children: [
|
|
304
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
305
|
+
value: "theme",
|
|
306
|
+
control: /*#__PURE__*/ _jsx(Radio, {
|
|
307
|
+
size: "small"
|
|
308
|
+
}),
|
|
309
|
+
label: "Use my site's theme colors",
|
|
310
|
+
disabled: busy || !hostId
|
|
311
|
+
}),
|
|
312
|
+
/*#__PURE__*/ _jsx(FormControlLabel, {
|
|
313
|
+
value: "custom",
|
|
314
|
+
control: /*#__PURE__*/ _jsx(Radio, {
|
|
315
|
+
size: "small"
|
|
316
|
+
}),
|
|
317
|
+
label: "Choose colors",
|
|
318
|
+
disabled: busy
|
|
319
|
+
})
|
|
320
|
+
]
|
|
321
|
+
}),
|
|
322
|
+
paletteSource === 'custom' ? /*#__PURE__*/ _jsxs(Stack, {
|
|
323
|
+
direction: "row",
|
|
324
|
+
spacing: 1,
|
|
325
|
+
sx: {
|
|
326
|
+
alignItems: 'center',
|
|
327
|
+
flexWrap: 'wrap'
|
|
328
|
+
},
|
|
329
|
+
children: [
|
|
330
|
+
colors.map((color, index)=>/*#__PURE__*/ _jsxs(Stack, {
|
|
331
|
+
direction: "row",
|
|
332
|
+
sx: {
|
|
333
|
+
alignItems: 'center'
|
|
334
|
+
},
|
|
335
|
+
children: [
|
|
336
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
337
|
+
type: "color",
|
|
338
|
+
size: "small",
|
|
339
|
+
value: color,
|
|
340
|
+
onChange: (event)=>setColors((current)=>current.map((value, at)=>at === index ? event.target.value : value)),
|
|
341
|
+
disabled: busy,
|
|
342
|
+
slotProps: {
|
|
343
|
+
htmlInput: {
|
|
344
|
+
'aria-label': `Color ${index + 1}`
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
sx: {
|
|
348
|
+
width: 64
|
|
349
|
+
}
|
|
350
|
+
}),
|
|
351
|
+
colors.length > 1 ? /*#__PURE__*/ _jsx(IconButton, {
|
|
352
|
+
size: "small",
|
|
353
|
+
"aria-label": `Remove color ${index + 1}`,
|
|
354
|
+
onClick: ()=>setColors((current)=>current.filter((_value, at)=>at !== index)),
|
|
355
|
+
disabled: busy,
|
|
356
|
+
children: '×'
|
|
357
|
+
}) : null
|
|
358
|
+
]
|
|
359
|
+
}, index)),
|
|
360
|
+
colors.length < AI_SVG_MAX_COLORS ? /*#__PURE__*/ _jsx(Button, {
|
|
361
|
+
size: "small",
|
|
362
|
+
onClick: ()=>setColors((current)=>[
|
|
363
|
+
...current,
|
|
364
|
+
'#333333'
|
|
365
|
+
]),
|
|
366
|
+
disabled: busy,
|
|
367
|
+
children: 'Add a color'
|
|
368
|
+
}) : null
|
|
369
|
+
]
|
|
370
|
+
}) : null
|
|
371
|
+
]
|
|
372
|
+
}) : null,
|
|
373
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
374
|
+
select: true,
|
|
375
|
+
size: "small",
|
|
376
|
+
label: "How many",
|
|
377
|
+
value: count,
|
|
378
|
+
onChange: (event)=>setCount(Number(event.target.value)),
|
|
379
|
+
disabled: busy,
|
|
380
|
+
sx: {
|
|
381
|
+
maxWidth: 160
|
|
382
|
+
},
|
|
383
|
+
children: Array.from({
|
|
384
|
+
length: AI_IMAGE_MAX_COUNT
|
|
385
|
+
}, (_unused, index)=>index + 1).map((value)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
386
|
+
value: value,
|
|
387
|
+
children: value
|
|
388
|
+
}, value))
|
|
389
|
+
}),
|
|
390
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
391
|
+
variant: "body2",
|
|
392
|
+
color: "text.secondary",
|
|
393
|
+
children: aiMediaCreditEstimate(mode, count)
|
|
394
|
+
}),
|
|
395
|
+
busy ? /*#__PURE__*/ _jsxs(Stack, {
|
|
396
|
+
spacing: 1,
|
|
397
|
+
children: [
|
|
398
|
+
/*#__PURE__*/ _jsx(LinearProgress, {}),
|
|
399
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
400
|
+
variant: "body2",
|
|
401
|
+
color: "text.secondary",
|
|
402
|
+
children: 'Making your pictures and adding them to the library…'
|
|
403
|
+
})
|
|
404
|
+
]
|
|
405
|
+
}) : null,
|
|
406
|
+
notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
407
|
+
severity: notice.severity,
|
|
408
|
+
children: notice.text
|
|
409
|
+
}) : null
|
|
410
|
+
]
|
|
411
|
+
})
|
|
412
|
+
}),
|
|
413
|
+
/*#__PURE__*/ _jsxs(DialogActions, {
|
|
414
|
+
children: [
|
|
415
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
416
|
+
onClick: onClose,
|
|
417
|
+
disabled: busy,
|
|
418
|
+
children: 'Close'
|
|
419
|
+
}),
|
|
420
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
421
|
+
variant: "contained",
|
|
422
|
+
onClick: ()=>void create(),
|
|
423
|
+
disabled: busy || !prompt.trim(),
|
|
424
|
+
children: busy ? 'Creating…' : 'Create'
|
|
425
|
+
})
|
|
426
|
+
]
|
|
427
|
+
})
|
|
428
|
+
]
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
export default AiMediaCreateButton;
|
|
432
|
+
|
|
433
|
+
//# sourceMappingURL=ai-media-create.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-media-create.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lockdownRefusalText, parseLockdownRefusal } from '@aglyn/aglyn'\nimport type { ConsoleMediaLibraryZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n IconButton,\n LinearProgress,\n MenuItem,\n Radio,\n RadioGroup,\n Stack,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n} from '@mui/material'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { aiMediaCreditsPerPicture } from '../model/ai-media-credits'\nimport {\n AI_IMAGE_ASPECT_RATIOS,\n AI_IMAGE_MAX_COUNT,\n AI_IMAGE_PROMPT_MAX_CHARS,\n AI_SVG_MAX_COLORS,\n AI_SVG_STYLES,\n aiImagePhotosOffered,\n type AiImageAspectRatio,\n type AiImageMode,\n type AiSvgStyle,\n} from '../providers/image-contract'\n\n/**\n * \"Create with AI\" in Media (AGL-3602): pictures from a description, added to\n * the library that is open, through the `mediaLibrary` zone beside Upload\n * media and in the library's empty state.\n *\n * It draws from the shell's gates alone — the plan, the member's\n * `ai.generate`, the plugin being on for the workspace and the site — and asks\n * no server anything until someone creates a picture: the door decides then,\n * and the dialog says what it decided. Two modes: an Illustration (an SVG the\n * text AI draws, wherever text AI runs) and, where the deployment makes them,\n * a Photo.\n */\n\n/** Where the shell sends a reader to buy what the plan lacks (AGL-3601). */\nexport interface AiMediaUpgrade {\n billingHref: string\n canManageBilling: boolean\n}\n\nexport interface AiMediaCreateButtonProps extends ConsoleMediaLibraryZoneProps {\n /**\n * `false` when the shell mounted this as its own upsell: the plan lacks AI\n * generation and an add-on would grant it. Absent means entitled.\n */\n entitled?: boolean\n upgrade?: AiMediaUpgrade\n}\n\n/** The words each shape is offered in. */\nconst ASPECT_LABELS: Record<AiImageAspectRatio, string> = {\n '1:1': 'Square',\n '4:3': 'Landscape',\n '3:4': 'Portrait',\n '16:9': 'Wide',\n '9:16': 'Tall',\n}\n\n/** The words each kind of illustration is offered in. */\nexport const AI_SVG_STYLE_LABELS: Record<AiSvgStyle, string> = {\n illustration: 'Illustration',\n icon: 'Icon',\n pattern: 'Pattern',\n logo: 'Logo mark',\n}\n\n/** The sentence the estimate reads as, before anything is spent. */\nexport function aiMediaCreditEstimate(mode: AiImageMode, count: number): string {\n const each = aiMediaCreditsPerPicture(mode)\n const pictures = count === 1 ? '1 picture' : `${count} pictures`\n return (\n `${pictures} uses about ${(count * each).toLocaleString()} AI credits ` +\n `(about ${each.toLocaleString()} each). A picture that is held back or does not come out is not charged.`\n )\n}\n\nexport function AiMediaCreateButton(props: AiMediaCreateButtonProps) {\n const { orgId, entitled, upgrade } = props\n const [open, setOpen] = useState(false)\n if (!orgId) return null\n const button = (\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n onClick={() => setOpen(true)}\n >\n {'Create with AI'}\n </Button>\n )\n if (entitled === false) {\n if (!upgrade) return null\n return (\n <>\n {button}\n <Dialog open={open} onClose={() => setOpen(false)} fullWidth maxWidth=\"xs\">\n <DialogTitle>{'Create images with AI'}</DialogTitle>\n <DialogContent>\n <Typography>\n {upgrade.canManageBilling\n ? 'Creating pictures and illustrations comes with the AI add-on.'\n : 'Creating pictures and illustrations comes with the AI add-on. Ask an owner or admin of this workspace to add it.'}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setOpen(false)}>{'Close'}</Button>\n {upgrade.canManageBilling ? (\n <Button variant=\"contained\" href={upgrade.billingHref}>\n {'See the AI add-on'}\n </Button>\n ) : null}\n </DialogActions>\n </Dialog>\n </>\n )\n }\n return (\n <>\n {button}\n <AiMediaCreateDialog {...props} orgId={orgId} open={open} onClose={() => setOpen(false)} />\n </>\n )\n}\n\nexport interface AiMediaCreateDialogProps\n extends Pick<ConsoleMediaLibraryZoneProps, 'hostId' | 'library' | 'folderId' | 'onCreated'> {\n open: boolean\n onClose: () => void\n orgId: string\n}\n\nexport function AiMediaCreateDialog({\n open,\n onClose,\n orgId,\n hostId,\n library,\n folderId,\n onCreated,\n}: AiMediaCreateDialogProps) {\n const { data: user } = useUser()\n const userRef = useRef(user)\n userRef.current = user\n const photos = aiImagePhotosOffered()\n const [mode, setMode] = useState<AiImageMode>(photos ? 'photo' : 'illustration')\n const [style, setStyle] = useState<AiSvgStyle>('illustration')\n // The site theme's colors need a site; the organization's library names none.\n const [paletteSource, setPaletteSource] = useState<'theme' | 'custom'>(hostId ? 'theme' : 'custom')\n const [colors, setColors] = useState<string[]>(['#1a73e8', '#fbbc04'])\n const [prompt, setPrompt] = useState('')\n const [aspectRatio, setAspectRatio] = useState<AiImageAspectRatio>('1:1')\n const [count, setCount] = useState(1)\n const [busy, setBusy] = useState(false)\n const [notice, setNotice] = useState<{ severity: 'error' | 'warning'; text: string } | null>(null)\n\n useEffect(() => {\n if (open) setNotice(null)\n }, [open])\n\n const create = useCallback(async () => {\n const description = prompt.trim()\n if (!description) return\n setBusy(true)\n setNotice(null)\n try {\n const response = await authorizedFetch(userRef.current, '/api/ai/media/images', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n orgId,\n library,\n hostId,\n folderId,\n mode,\n prompt: description,\n aspectRatio,\n count,\n ...(mode === 'illustration'\n ? {\n style,\n palette:\n paletteSource === 'theme' ? { source: 'theme' } : { source: 'custom', colors },\n }\n : {}),\n }),\n })\n const payload = await response.json().catch(() => null)\n if (!response.ok) {\n const locked = parseLockdownRefusal(response.status, payload)\n setNotice({\n severity: 'error',\n text: locked\n ? lockdownRefusalText(locked)\n : String(payload?.error ?? 'The pictures could not be made — try again.'),\n })\n return\n }\n const ids: string[] = Array.isArray(payload?.mediaIds) ? payload.mediaIds : []\n onCreated(ids)\n const missing = Number(payload?.filtered ?? 0) + Number(payload?.failed ?? 0)\n if (missing > 0) {\n setNotice({\n severity: 'warning',\n text:\n `Added ${ids.length} of ${count} to the library. ` +\n (payload?.warning\n ? String(payload.warning)\n : 'The rest were held back and were not charged.'),\n })\n return\n }\n setPrompt('')\n onClose()\n } catch {\n setNotice({ severity: 'error', text: 'The pictures could not be made — try again.' })\n } finally {\n setBusy(false)\n }\n }, [prompt, orgId, library, hostId, folderId, mode, aspectRatio, count, style, paletteSource, colors, onCreated, onClose])\n\n return (\n <Dialog open={open} onClose={busy ? undefined : onClose} fullWidth maxWidth=\"sm\">\n <DialogTitle>{'Create images with AI'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n {photos ? (\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={mode}\n onChange={(_event, next) => {\n if (next) setMode(next)\n }}\n aria-label=\"What to make\"\n disabled={busy}\n >\n <ToggleButton value=\"photo\">{'Photo'}</ToggleButton>\n <ToggleButton value=\"illustration\">{'Illustration or icon'}</ToggleButton>\n </ToggleButtonGroup>\n ) : null}\n {mode === 'illustration' ? (\n <TextField\n select\n size=\"small\"\n label=\"Kind\"\n value={style}\n onChange={(event) => setStyle(event.target.value as AiSvgStyle)}\n disabled={busy}\n sx={{ maxWidth: 240 }}\n helperText={\n style === 'logo'\n ? 'A simple symbol, without lettering. Not a real brand’s logo.'\n : style === 'pattern'\n ? 'A seamless background that tiles.'\n : 'Drawn as an SVG, sharp at any size.'\n }\n >\n {AI_SVG_STYLES.map((value) => (\n <MenuItem key={value} value={value}>\n {AI_SVG_STYLE_LABELS[value]}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n <TextField\n label={mode === 'photo' ? 'Describe the picture' : 'Describe what to draw'}\n placeholder={\n mode === 'photo'\n ? 'A sunlit bakery counter with fresh sourdough loaves, warm morning light'\n : 'A friendly delivery van with a parcel, simple and flat'\n }\n value={prompt}\n onChange={(event) => setPrompt(event.target.value.slice(0, AI_IMAGE_PROMPT_MAX_CHARS))}\n multiline\n minRows={3}\n autoFocus\n disabled={busy}\n helperText=\"The description becomes each picture's alt text, which you can edit.\"\n />\n <Stack spacing={0.5}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Shape'}\n </Typography>\n <ToggleButtonGroup\n size=\"small\"\n exclusive\n value={aspectRatio}\n onChange={(_event, next) => {\n if (next) setAspectRatio(next)\n }}\n aria-label=\"Shape\"\n disabled={busy}\n sx={{ flexWrap: 'wrap' }}\n >\n {AI_IMAGE_ASPECT_RATIOS.map((ratio) => (\n <ToggleButton key={ratio} value={ratio} aria-label={`${ASPECT_LABELS[ratio]} ${ratio}`}>\n {`${ASPECT_LABELS[ratio]} ${ratio}`}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n </Stack>\n {mode === 'illustration' ? (\n <Stack spacing={1}>\n <RadioGroup\n value={paletteSource}\n onChange={(event) => setPaletteSource(event.target.value as 'theme' | 'custom')}\n aria-label=\"Colors\"\n >\n <FormControlLabel\n value=\"theme\"\n control={<Radio size=\"small\" />}\n label=\"Use my site's theme colors\"\n disabled={busy || !hostId}\n />\n <FormControlLabel\n value=\"custom\"\n control={<Radio size=\"small\" />}\n label=\"Choose colors\"\n disabled={busy}\n />\n </RadioGroup>\n {paletteSource === 'custom' ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>\n {colors.map((color, index) => (\n <Stack key={index} direction=\"row\" sx={{ alignItems: 'center' }}>\n <TextField\n type=\"color\"\n size=\"small\"\n value={color}\n onChange={(event) =>\n setColors((current) =>\n current.map((value, at) => (at === index ? event.target.value : value)),\n )\n }\n disabled={busy}\n slotProps={{ htmlInput: { 'aria-label': `Color ${index + 1}` } }}\n sx={{ width: 64 }}\n />\n {colors.length > 1 ? (\n <IconButton\n size=\"small\"\n aria-label={`Remove color ${index + 1}`}\n onClick={() => setColors((current) => current.filter((_value, at) => at !== index))}\n disabled={busy}\n >\n {'×'}\n </IconButton>\n ) : null}\n </Stack>\n ))}\n {colors.length < AI_SVG_MAX_COLORS ? (\n <Button size=\"small\" onClick={() => setColors((current) => [...current, '#333333'])} disabled={busy}>\n {'Add a color'}\n </Button>\n ) : null}\n </Stack>\n ) : null}\n </Stack>\n ) : null}\n <TextField\n select\n size=\"small\"\n label=\"How many\"\n value={count}\n onChange={(event) => setCount(Number(event.target.value))}\n disabled={busy}\n sx={{ maxWidth: 160 }}\n >\n {Array.from({ length: AI_IMAGE_MAX_COUNT }, (_unused, index) => index + 1).map((value) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </TextField>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {aiMediaCreditEstimate(mode, count)}\n </Typography>\n {busy ? (\n <Stack spacing={1}>\n <LinearProgress />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Making your pictures and adding them to the library…'}\n </Typography>\n </Stack>\n ) : null}\n {notice ? <Alert severity={notice.severity}>{notice.text}</Alert> : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose} disabled={busy}>\n {'Close'}\n </Button>\n <Button variant=\"contained\" onClick={() => void create()} disabled={busy || !prompt.trim()}>\n {busy ? 'Creating…' : 'Create'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nexport default AiMediaCreateButton\n"],"names":["lockdownRefusalText","parseLockdownRefusal","mdiCreation","MdiIcon","authorizedFetch","useUser","Alert","Button","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","IconButton","LinearProgress","MenuItem","Radio","RadioGroup","Stack","TextField","ToggleButton","ToggleButtonGroup","Typography","useCallback","useEffect","useRef","useState","aiMediaCreditsPerPicture","AI_IMAGE_ASPECT_RATIOS","AI_IMAGE_MAX_COUNT","AI_IMAGE_PROMPT_MAX_CHARS","AI_SVG_MAX_COLORS","AI_SVG_STYLES","aiImagePhotosOffered","ASPECT_LABELS","AI_SVG_STYLE_LABELS","illustration","icon","pattern","logo","aiMediaCreditEstimate","mode","count","each","pictures","toLocaleString","AiMediaCreateButton","props","orgId","entitled","upgrade","open","setOpen","button","size","variant","startIcon","path","onClick","onClose","fullWidth","maxWidth","canManageBilling","href","billingHref","AiMediaCreateDialog","hostId","library","folderId","onCreated","data","user","userRef","current","photos","setMode","style","setStyle","paletteSource","setPaletteSource","colors","setColors","prompt","setPrompt","aspectRatio","setAspectRatio","setCount","busy","setBusy","notice","setNotice","create","description","trim","response","method","headers","body","JSON","stringify","palette","source","payload","json","catch","ok","locked","status","severity","text","String","error","ids","Array","isArray","mediaIds","missing","Number","filtered","failed","length","warning","undefined","spacing","sx","pt","exclusive","value","onChange","_event","next","aria-label","disabled","select","label","event","target","helperText","map","placeholder","slice","multiline","minRows","autoFocus","color","flexWrap","ratio","control","direction","alignItems","index","type","at","slotProps","htmlInput","width","filter","_value","from","_unused"],"mappings":"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"}
|