@canva/cli 1.0.0 → 1.0.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.
- package/cli.js +1 -1
- package/package.json +1 -1
- package/templates/data_connector/src/api/data_sources/designs.tsx +1 -1
- package/templates/data_connector/src/api/data_sources/templates.tsx +1 -1
- package/templates/data_connector/src/components/header.tsx +1 -1
- package/templates/data_connector/src/context/use_app_context.ts +2 -2
- package/templates/data_connector/src/entrypoint.tsx +1 -1
- package/templates/data_connector/src/pages/error.tsx +1 -1
- package/templates/data_connector/src/pages/login.tsx +1 -1
- package/templates/data_connector/src/paths.ts +7 -0
- package/templates/data_connector/src/routes/protected_route.tsx +1 -1
- package/templates/data_connector/src/routes/routes.tsx +5 -9
- package/templates/gen_ai/src/components/footer.tsx +16 -3
- package/templates/gen_ai/src/components/loading_results.tsx +1 -1
- package/templates/gen_ai/src/components/prompt_input.tsx +1 -1
- package/templates/gen_ai/src/components/remaining_credits.tsx +28 -20
- package/templates/gen_ai/src/components/report_box.tsx +1 -1
- package/templates/gen_ai/src/components/tests/remaining_credit.tests.tsx +5 -1
- package/templates/gen_ai/src/context/use_app_context.ts +2 -2
- package/templates/gen_ai/src/pages/error.tsx +1 -1
- package/templates/gen_ai/src/paths.ts +4 -0
- package/templates/gen_ai/src/routes/routes.tsx +4 -6
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { SearchFilter } from "src/components/inputs/search_filter";
|
|
14
14
|
import { SelectField } from "src/components/inputs/select_field";
|
|
15
15
|
import { useAppContext } from "src/context";
|
|
16
|
-
import { Paths } from "src/
|
|
16
|
+
import { Paths } from "src/paths";
|
|
17
17
|
import { dateCell, numberCell, stringCell } from "src/utils";
|
|
18
18
|
import type { CanvaItemResponse } from "../connect_client";
|
|
19
19
|
import { DataAPIError, DataSourceHandler } from "../data_source";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { SearchFilter } from "src/components/inputs/search_filter";
|
|
19
19
|
import { SelectField } from "src/components/inputs/select_field";
|
|
20
20
|
import { useAppContext } from "src/context";
|
|
21
|
-
import { Paths } from "src/
|
|
21
|
+
import { Paths } from "src/paths";
|
|
22
22
|
import { dateCell, stringCell } from "src/utils";
|
|
23
23
|
import type { CanvaItemResponse } from "../connect_client";
|
|
24
24
|
import { DataAPIError, DataSourceHandler } from "../data_source";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
|
-
import type { AppContextType } from "
|
|
3
|
-
import { AppContext } from "
|
|
2
|
+
import type { AppContextType } from "./app_context";
|
|
3
|
+
import { AppContext } from "./app_context";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A custom React hook to access the application-wide state and methods provided by the ContextProvider using React Context.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Button, Rows, Text } from "@canva/app-ui-kit";
|
|
2
2
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
3
3
|
import { useNavigate } from "react-router-dom";
|
|
4
|
-
import { Paths } from "src/
|
|
4
|
+
import { Paths } from "src/paths";
|
|
5
5
|
import * as styles from "styles/components.css";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -11,9 +11,9 @@ import { defineMessages, FormattedMessage, useIntl } from "react-intl";
|
|
|
11
11
|
import { useNavigate } from "react-router-dom";
|
|
12
12
|
import { scope } from "src/api";
|
|
13
13
|
import { Header } from "src/components";
|
|
14
|
+
import { Paths } from "src/paths";
|
|
14
15
|
import * as styles from "styles/components.css";
|
|
15
16
|
import { useAppContext } from "../context";
|
|
16
|
-
import { Paths } from "../routes";
|
|
17
17
|
|
|
18
18
|
export const Login = () => {
|
|
19
19
|
const intl = useIntl();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
2
|
import { useNavigate } from "react-router-dom";
|
|
3
|
+
import { Paths } from "src/paths";
|
|
3
4
|
import { useAppContext } from "../context";
|
|
4
|
-
import { Paths } from "../routes";
|
|
5
5
|
|
|
6
6
|
interface ProtectedRouteProps {
|
|
7
7
|
children: React.ReactNode;
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { Entrypoint } from "src/entrypoint";
|
|
2
2
|
import { Home } from "src/home";
|
|
3
|
-
import { DataSourceConfig
|
|
3
|
+
import { DataSourceConfig } from "src/pages/data_source_config";
|
|
4
|
+
import { ErrorPage } from "src/pages/error";
|
|
5
|
+
import { Login } from "src/pages/login";
|
|
6
|
+
import { SelectSource } from "src/pages/select_source";
|
|
7
|
+
import { Paths } from "src/paths";
|
|
4
8
|
import { ProtectedRoute } from "./protected_route";
|
|
5
9
|
|
|
6
|
-
export enum Paths {
|
|
7
|
-
ENTRYPOINT = "/",
|
|
8
|
-
LOGIN = "/login",
|
|
9
|
-
DATA_SOURCE_SELECTION = "/data-source-selection",
|
|
10
|
-
DATA_SOURCE_CONFIG = "/data-source-config",
|
|
11
|
-
ERRORS = "/errors/:retry",
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
export const routes = [
|
|
15
11
|
{
|
|
16
12
|
path: Paths.ENTRYPOINT,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Button, Rows } from "@canva/app-ui-kit";
|
|
2
|
+
import { getPlatformInfo } from "@canva/platform";
|
|
2
3
|
import { useIntl } from "react-intl";
|
|
3
4
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
4
5
|
import { purchaseCredits, queueImageGeneration } from "src/api";
|
|
5
6
|
import { RemainingCredits } from "src/components";
|
|
6
7
|
import { NUMBER_OF_IMAGES_TO_GENERATE } from "src/config";
|
|
7
8
|
import { useAppContext } from "src/context";
|
|
8
|
-
import { Paths } from "src/
|
|
9
|
+
import { Paths } from "src/paths";
|
|
9
10
|
import { getObsceneWords } from "src/utils";
|
|
10
11
|
import { FooterMessages as Messages } from "./footer.messages";
|
|
11
12
|
|
|
@@ -13,6 +14,7 @@ export const Footer = () => {
|
|
|
13
14
|
const navigate = useNavigate();
|
|
14
15
|
const { pathname } = useLocation();
|
|
15
16
|
const isRootRoute = pathname === Paths.HOME;
|
|
17
|
+
const platformInfo = getPlatformInfo();
|
|
16
18
|
const {
|
|
17
19
|
setAppError,
|
|
18
20
|
promptInput,
|
|
@@ -84,8 +86,11 @@ export const Footer = () => {
|
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
const onPurchaseMoreCredits = async () => {
|
|
87
|
-
|
|
89
|
+
if (!platformInfo.canAcceptPayments) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
88
92
|
|
|
93
|
+
const { credits } = await purchaseCredits();
|
|
89
94
|
setRemainingCredits(credits);
|
|
90
95
|
};
|
|
91
96
|
|
|
@@ -108,6 +113,12 @@ export const Footer = () => {
|
|
|
108
113
|
onClick: onPurchaseMoreCredits,
|
|
109
114
|
value: intl.formatMessage(Messages.purchaseMoreCredits),
|
|
110
115
|
visible: !hasRemainingCredits,
|
|
116
|
+
disabled: !platformInfo.canAcceptPayments,
|
|
117
|
+
tooltip: intl.formatMessage({
|
|
118
|
+
defaultMessage: "Payment not available on this platform.",
|
|
119
|
+
description:
|
|
120
|
+
"Tooltip text when payment functionality is not available on the current platform. ",
|
|
121
|
+
}),
|
|
111
122
|
},
|
|
112
123
|
{
|
|
113
124
|
variant: "secondary" as const,
|
|
@@ -124,7 +135,7 @@ export const Footer = () => {
|
|
|
124
135
|
return (
|
|
125
136
|
<Rows spacing="1u">
|
|
126
137
|
{footerButtons.map(
|
|
127
|
-
({ visible, variant, onClick, value }) =>
|
|
138
|
+
({ visible, variant, onClick, value, disabled, tooltip }) =>
|
|
128
139
|
visible && (
|
|
129
140
|
<Button
|
|
130
141
|
key={value}
|
|
@@ -132,6 +143,8 @@ export const Footer = () => {
|
|
|
132
143
|
onClick={onClick}
|
|
133
144
|
loading={loadingApp}
|
|
134
145
|
stretch={true}
|
|
146
|
+
disabled={disabled}
|
|
147
|
+
tooltipLabel={tooltip}
|
|
135
148
|
>
|
|
136
149
|
{value}
|
|
137
150
|
</Button>
|
|
@@ -12,7 +12,7 @@ import { FormattedMessage, useIntl } from "react-intl";
|
|
|
12
12
|
import { useNavigate } from "react-router-dom";
|
|
13
13
|
import { cancelImageGenerationJob, getImageGenerationJobStatus } from "src/api";
|
|
14
14
|
import { useAppContext } from "src/context";
|
|
15
|
-
import { Paths } from "src/
|
|
15
|
+
import { Paths } from "src/paths";
|
|
16
16
|
|
|
17
17
|
const INTERVAL_DURATION_IN_MS = 100;
|
|
18
18
|
const TOTAL_PROGRESS_PERCENTAGE = 100;
|
|
@@ -9,7 +9,7 @@ import { useState } from "react";
|
|
|
9
9
|
import { useIntl } from "react-intl";
|
|
10
10
|
import { useLocation } from "react-router-dom";
|
|
11
11
|
import { useAppContext } from "src/context";
|
|
12
|
-
import { Paths } from "src/
|
|
12
|
+
import { Paths } from "src/paths";
|
|
13
13
|
import { PromptInputMessages as Messages } from "./prompt_input.messages";
|
|
14
14
|
|
|
15
15
|
// @TODO: Adjust according to your specific requirements.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Link, Rows, Text, TextPlaceholder } from "@canva/app-ui-kit";
|
|
2
|
-
import { requestOpenExternalUrl } from "@canva/platform";
|
|
2
|
+
import { getPlatformInfo, requestOpenExternalUrl } from "@canva/platform";
|
|
3
3
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
4
4
|
import { useAppContext } from "src/context";
|
|
5
5
|
|
|
@@ -8,6 +8,7 @@ const PURCHASE_URL = "https://example.com";
|
|
|
8
8
|
|
|
9
9
|
export const RemainingCredits = (): JSX.Element | undefined => {
|
|
10
10
|
const { remainingCredits, loadingApp } = useAppContext();
|
|
11
|
+
const platformInfo = getPlatformInfo();
|
|
11
12
|
|
|
12
13
|
const RemainingCreditsText = () => {
|
|
13
14
|
if (loadingApp) {
|
|
@@ -50,25 +51,32 @@ export const RemainingCredits = (): JSX.Element | undefined => {
|
|
|
50
51
|
<Rows spacing="0">
|
|
51
52
|
<RemainingCreditsText />
|
|
52
53
|
<Text alignment="center" size="small">
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
54
|
+
{platformInfo.canAcceptPayments ? (
|
|
55
|
+
<FormattedMessage
|
|
56
|
+
defaultMessage="Purchase more credits at <link>example.com</link>."
|
|
57
|
+
description="A message to prompt the user to purchase more credits. Do not translate <link>example.com</link>."
|
|
58
|
+
values={{
|
|
59
|
+
link: (chunks) => (
|
|
60
|
+
<Link
|
|
61
|
+
href={PURCHASE_URL}
|
|
62
|
+
requestOpenExternalUrl={() => openExternalUrl(PURCHASE_URL)}
|
|
63
|
+
tooltipLabel={intl.formatMessage({
|
|
64
|
+
defaultMessage: "Example Co. website",
|
|
65
|
+
description:
|
|
66
|
+
"A title for a link to the website of Example Co.",
|
|
67
|
+
})}
|
|
68
|
+
>
|
|
69
|
+
{chunks}
|
|
70
|
+
</Link>
|
|
71
|
+
),
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
) : (
|
|
75
|
+
<FormattedMessage
|
|
76
|
+
defaultMessage="Open this app in a web browser to learn how to purchase more credits."
|
|
77
|
+
description="A message shown when platform doesn't allow external payment links"
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
72
80
|
</Text>
|
|
73
81
|
</Rows>
|
|
74
82
|
);
|
|
@@ -34,7 +34,7 @@ export const ReportBox = (): JSX.Element => {
|
|
|
34
34
|
<Link
|
|
35
35
|
href={REPORT_URL}
|
|
36
36
|
requestOpenExternalUrl={() => openExternalUrl(REPORT_URL)}
|
|
37
|
-
|
|
37
|
+
tooltipLabel={intl.formatMessage({
|
|
38
38
|
defaultMessage: "Report content",
|
|
39
39
|
description:
|
|
40
40
|
"A title for a link to report AI generated content that is problematic",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable formatjs/no-literal-string-in-jsx */
|
|
2
2
|
import { TestAppI18nProvider } from "@canva/app-i18n-kit";
|
|
3
3
|
import { TestAppUiProvider } from "@canva/app-ui-kit";
|
|
4
|
-
import { requestOpenExternalUrl } from "@canva/platform";
|
|
4
|
+
import { getPlatformInfo, requestOpenExternalUrl } from "@canva/platform";
|
|
5
5
|
import type { RenderResult } from "@testing-library/react";
|
|
6
6
|
import { fireEvent, render } from "@testing-library/react";
|
|
7
7
|
import React from "react";
|
|
@@ -20,9 +20,13 @@ function renderInTestProvider(node: React.ReactNode): RenderResult {
|
|
|
20
20
|
// For more information on testing with the Canva Apps SDK, see https://www.canva.dev/docs/apps/testing/
|
|
21
21
|
describe("Remaining Credit Tests", () => {
|
|
22
22
|
const mockRequestOpenExternalUrl = jest.mocked(requestOpenExternalUrl);
|
|
23
|
+
const mockGetPlatformInfo = jest.mocked(getPlatformInfo);
|
|
23
24
|
|
|
24
25
|
beforeEach(() => {
|
|
25
26
|
jest.resetAllMocks();
|
|
27
|
+
mockGetPlatformInfo.mockReturnValue({
|
|
28
|
+
canAcceptPayments: true,
|
|
29
|
+
});
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
it("should call requestOpenExternalUrl when the link is clicked", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
|
-
import type { AppContextType } from "
|
|
3
|
-
import { AppContext } from "
|
|
2
|
+
import type { AppContextType } from "./app_context";
|
|
3
|
+
import { AppContext } from "./app_context";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A custom React hook to access the application-wide state and methods provided by the ContextProvider using React Context.
|
|
@@ -2,7 +2,7 @@ import { Button, Rows, Text } from "@canva/app-ui-kit";
|
|
|
2
2
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
3
3
|
import { useNavigate } from "react-router-dom";
|
|
4
4
|
import { useAppContext } from "src/context";
|
|
5
|
-
import { Paths } from "src/
|
|
5
|
+
import { Paths } from "src/paths";
|
|
6
6
|
import * as styles from "styles/components.css";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Home } from "src/home";
|
|
2
|
-
import { ErrorPage
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
RESULTS = "/results",
|
|
7
|
-
}
|
|
2
|
+
import { ErrorPage } from "src/pages/error";
|
|
3
|
+
import { GeneratePage } from "src/pages/generate";
|
|
4
|
+
import { ResultsPage } from "src/pages/results";
|
|
5
|
+
import { Paths } from "src/paths";
|
|
8
6
|
|
|
9
7
|
export const routes = [
|
|
10
8
|
{
|