diff --git a/package-lock.json b/package-lock.json index ea2919e1d..ec829eefd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "@appwrite/console", "dependencies": { - "@appwrite.io/console": "^0.6.2", + "@appwrite.io/console": "npm:matej-appwrite-console-16x@0.6.4", "@appwrite.io/pink": "0.23.0", "@appwrite.io/pink-icons": "0.23.0", "@popperjs/core": "^2.11.8", @@ -15,6 +15,7 @@ "@stripe/stripe-js": "^3.4.0", "ai": "^2.2.11", "analytics": "^0.8.9", + "cron-parser": "^4.9.0", "dayjs": "^1.11.9", "deep-equal": "^2.2.2", "dotenv": "^16.3.1", @@ -148,9 +149,10 @@ "integrity": "sha512-TD+xbmsBLyYy/IxFimW/YL/9L2IEnM7/EoV9Aeh56U64Ify8o27HJcKjo38XY9Tcn0uOq1AX3thkKgvtWvwFQg==" }, "node_modules/@appwrite.io/console": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@appwrite.io/console/-/console-0.6.2.tgz", - "integrity": "sha512-3qYknuFwhvTN2GnPB8G1w5DgxfVorGtfj4uuEaXbTmMUmjA8fHaW5VkJriuUxCi6/TpxDxqV/hhEkdoXL+5H4w==" + "name": "matej-appwrite-console-16x", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/matej-appwrite-console-16x/-/matej-appwrite-console-16x-0.6.4.tgz", + "integrity": "sha512-hovc+6HFyC20lUmlD0R5kAsDMBLXXJWEES2mUAaKG56aQ1wOwQRhVOIUGmvX/1EasiUOq5dH/5uzrU+fl5C+Dw==" }, "node_modules/@appwrite.io/pink": { "version": "0.23.0", @@ -4020,6 +4022,17 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7019,6 +7032,14 @@ "yallist": "^3.0.2" } }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "engines": { + "node": ">=12" + } + }, "node_modules/lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", diff --git a/package.json b/package.json index 42ec216dd..cf05a91e8 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "e2e:ui": "playwright test tests/e2e --ui" }, "dependencies": { - "@appwrite.io/console": "^0.6.2", + "@appwrite.io/console": "npm:matej-appwrite-console-16x@0.6.4", "@appwrite.io/pink": "0.23.0", "@appwrite.io/pink-icons": "0.23.0", "@popperjs/core": "^2.11.8", @@ -28,6 +28,7 @@ "@stripe/stripe-js": "^3.4.0", "ai": "^2.2.11", "analytics": "^0.8.9", + "cron-parser": "^4.9.0", "dayjs": "^1.11.9", "deep-equal": "^2.2.2", "dotenv": "^16.3.1", diff --git a/src/lib/actions/analytics.ts b/src/lib/actions/analytics.ts index af3cc1979..5f4c5e18b 100644 --- a/src/lib/actions/analytics.ts +++ b/src/lib/actions/analytics.ts @@ -227,13 +227,16 @@ export enum Submit { FunctionUpdateLogging = 'submit_function_update_logging', FunctionUpdateTimeout = 'submit_function_update_timeout', FunctionUpdateEvents = 'submit_function_update_events', + FunctionUpdateScopes = 'submit_function_update_scopes', FunctionConnectRepo = 'submit_function_connect_repo', FunctionDisconnectRepo = 'submit_function_disconnect_repo', FunctionRedeploy = 'submit_function_redeploy', DeploymentCreate = 'submit_deployment_create', DeploymentDelete = 'submit_deployment_delete', DeploymentUpdate = 'submit_deployment_update', + DeploymentCancel = 'submit_deployment_cancel', ExecutionCreate = 'submit_execution_create', + ExecutionDelete = 'submit_execution_delete', VariableCreate = 'submit_variable_create', VariableDelete = 'submit_variable_delete', VariableUpdate = 'submit_variable_update', diff --git a/src/lib/components/billing/creditsApplied.svelte b/src/lib/components/billing/creditsApplied.svelte index 6cf231e57..1010f0f5e 100644 --- a/src/lib/components/billing/creditsApplied.svelte +++ b/src/lib/components/billing/creditsApplied.svelte @@ -42,9 +42,7 @@ {/if} {#if couponData.credits >= 100} -

- Credits applied -

+

Credits applied

{:else} -{formatCurrency(couponData.credits)} {/if} diff --git a/src/lib/components/billing/estimatedTotalBox.svelte b/src/lib/components/billing/estimatedTotalBox.svelte index 52ac4faba..3ff31041c 100644 --- a/src/lib/components/billing/estimatedTotalBox.svelte +++ b/src/lib/components/billing/estimatedTotalBox.svelte @@ -32,9 +32,10 @@
+

{currentPlan.name} plan

{formatCurrency(currentPlan.price)}

diff --git a/src/lib/components/dropList.svelte b/src/lib/components/dropList.svelte index 0c802cffd..effecd4a6 100644 --- a/src/lib/components/dropList.svelte +++ b/src/lib/components/dropList.svelte @@ -36,10 +36,10 @@ }`}> {#if $$slots.list}
+ class="drop-section" + style={noMaxWidthList ? 'max-inline-size: 100%' : ''}>
diff --git a/src/lib/components/filters/content.svelte b/src/lib/components/filters/content.svelte index cb56ca1e5..c0477e6ee 100644 --- a/src/lib/components/filters/content.svelte +++ b/src/lib/components/filters/content.svelte @@ -6,96 +6,25 @@ InputText, InputTags, FormList, - InputSelectCheckbox + InputSelectCheckbox, + InputDateTime } from '$lib/elements/forms'; - import { Query } from '@appwrite.io/console'; import { createEventDispatcher, onMount } from 'svelte'; - import { tags, type Operator, queries, type TagValue } from './store'; + import { tags, operators, addFilter } from './store'; import type { Column } from '$lib/helpers/types'; import type { Writable } from 'svelte/store'; - import { tooltip } from '$lib/actions/tooltip'; + import { TagList } from '.'; + // We cast to any to not cause type errors in the input components + /* eslint @typescript-eslint/no-explicit-any: 'off' */ + export let value: any = null; export let columns: Writable; export let columnId: string | null = null; - - const dispatch = createEventDispatcher<{ - clear: void; - apply: { applied: number }; - }>(); + export let arrayValues: string[] = []; + export let operatorKey: string | null = null; + export let singleCondition = false; $: column = $columns.find((c) => c.id === columnId) as Column; - let arrayValues: string[] = []; - - dispatch('apply', { applied: $tags.length }); - - const operators: Record = { - 'starts with': { - toQuery: Query.startsWith, - toTag: (attribute, input) => `**${attribute}** starts with **${input}**`, - types: ['string'] - }, - 'ends with': { - toQuery: Query.endsWith, - toTag: (attribute, input) => `**${attribute}** ends with **${input}**`, - types: ['string'] - }, - 'greater than': { - toQuery: (attr, input) => Query.greaterThan(attr, Number(input)), - toTag: (attribute, input) => `**${attribute}** greater than **${input}**`, - types: ['integer', 'double', 'datetime'] - }, - 'greater than or equal': { - toQuery: (attr, input) => Query.greaterThanEqual(attr, Number(input)), - toTag: (attribute, input) => `**${attribute}** greater than or equal to **${input}**`, - types: ['integer', 'double', 'datetime'] - }, - 'less than': { - toQuery: Query.lessThan, - toTag: (attribute, input) => `**${attribute}** less than **${input}**`, - types: ['integer', 'double', 'datetime'] - }, - 'less than or equal': { - toQuery: Query.lessThanEqual, - toTag: (attribute, input) => `**${attribute}** less than or equal to **${input}**`, - types: ['integer', 'double', 'datetime'] - }, - equal: { - toQuery: Query.equal, - toTag: (attribute, input) => `**${attribute}** equal to **${input}**`, - types: ['string', 'integer', 'double', 'boolean'] - }, - 'not equal': { - toQuery: Query.notEqual, - toTag: (attribute, input) => `**${attribute}** not equal to **${input}**`, - types: ['string', 'integer', 'double', 'boolean'] - }, - 'is not null': { - toQuery: Query.isNotNull, - toTag: (attribute) => `**${attribute}** is not null`, - types: ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'], - hideInput: true - }, - 'is null': { - toQuery: Query.isNull, - toTag: (attribute) => `**${attribute}** is null`, - types: ['string', 'integer', 'double', 'boolean', 'datetime', 'relationship'], - hideInput: true - }, - contains: { - toQuery: Query.contains, - toTag: (attribute, input) => { - if (Array.isArray(input) && input.length > 2) { - return { - value: input, - tag: `**${attribute}** contains **${formatArray(input)}** ` - }; - } else { - return `**${attribute}** contains **${input}**`; - } - }, - types: ['string', 'integer', 'double', 'boolean', 'datetime', 'enum'] - } - }; $: operatorsForColumn = Object.entries(operators) .filter(([, v]) => v.types.includes(column?.type)) @@ -104,64 +33,39 @@ value: k })); - let operatorKey: string | null = null; $: operator = operatorKey ? operators[operatorKey] : null; $: { columnId; operatorKey = null; } - // We cast to any to not cause type errors in the input components - /* eslint @typescript-eslint/no-explicit-any: 'off' */ - let value: any = null; + $: isDisabled = !operator; onMount(() => { value = column?.array ? [] : null; + if (column?.type === 'datetime') { + const today = new Date(); + value = today.toISOString(); + } }); - // This Map is keyed by tags, and has a query as the value - function addFilter() { - if (!column || !operator) return; - if (column.array) { - queries.addFilter({ column, operator, value: arrayValues }); - columnId = null; - arrayValues = []; - } else { - queries.addFilter({ column, operator, value: value ?? '' }); - columnId = null; - value = null; - } + function addFilterAndReset() { + addFilter($columns, columnId, operatorKey, value, arrayValues); + columnId = null; + operatorKey = null; + value = null; + arrayValues = []; } - function tagFormat(node: HTMLElement) { - node.innerHTML = node.innerHTML.replace(/\*\*(.*?)\*\*/g, '$1'); - } - - function formatArray(array: string[]) { - if (!array?.length) return; - if (array.length > 2) { - return `${array[0]} or ${array.length - 1} others`; - } else { - return array.join(' or '); - } - } - - function isTypeTagValue(obj: any): obj is TagValue { - if (typeof obj === 'string') return false; - return ( - obj && - typeof obj.tag === 'string' && - (typeof obj.value === 'string' || - typeof obj.value === 'number' || - Array.isArray(obj.value)) - ); - } - - $: isDisabled = !operator; + const dispatch = createEventDispatcher<{ + clear: void; + apply: { applied: number }; + }>(); + dispatch('apply', { applied: $tags.length });
-
+
    ({ - label: value, - value, - checked: arrayValues.includes(value) + options={column?.elements?.map((e) => ({ + label: e?.label ?? e, + value: e?.value ?? e, + checked: arrayValues.includes(e?.value ?? e) }))}> {:else} @@ -210,7 +114,10 @@ id="value" bind:value placeholder="Select value" - options={column?.elements?.map((value) => ({ label: value, value }))} + options={column?.elements?.map((e) => ({ + label: e?.label ?? e, + value: e?.value ?? e + }))} label="Value" showLabel={false} /> {:else if column.type === 'integer' || column.type === 'double'} @@ -225,48 +132,29 @@ { label: 'False', value: false } ].filter(Boolean)} bind:value /> + {:else if column.type === 'datetime'} + {#key value} + + {/key} {:else} {/if}
{/if} {/if} - + {#if !singleCondition} + + {/if} -
    - {#each $tags as tag (tag)} - {#if isTypeTagValue(tag)} - - {:else} - - {/if} - {/each} -
+ {#if !singleCondition} +
    + +
+ {/if}
diff --git a/src/lib/layout/wizardSecondaryContent.svelte b/src/lib/layout/wizardSecondaryContent.svelte index 6b69d488a..908995692 100644 --- a/src/lib/layout/wizardSecondaryContent.svelte +++ b/src/lib/layout/wizardSecondaryContent.svelte @@ -4,8 +4,6 @@
-
- -
+
diff --git a/src/lib/layout/wizardSecondaryHeader.svelte b/src/lib/layout/wizardSecondaryHeader.svelte index bb74685db..048482de9 100644 --- a/src/lib/layout/wizardSecondaryHeader.svelte +++ b/src/lib/layout/wizardSecondaryHeader.svelte @@ -4,8 +4,18 @@ import { Button } from '$lib/elements/forms'; import { createEventDispatcher } from 'svelte'; - export let confirmExit = false; - export let href = ''; + type $$Props = + | { + confirmExit: boolean; + href?: string; + } + | { + confirmExit?: boolean; + href: string; + }; + + export let confirmExit: $$Props['confirmExit'] = false; + export let href: $$Props['href'] = ''; const dispatch = createEventDispatcher(); diff --git a/src/lib/stores/campaigns.ts b/src/lib/stores/campaigns.ts index cc95cda59..6ffc9e0f1 100644 --- a/src/lib/stores/campaigns.ts +++ b/src/lib/stores/campaigns.ts @@ -1,30 +1,119 @@ //campaign welcome and startup -type CampaignData = { +export type CampaignData = { title: string; description: string; + template: 'card' | 'review'; + data?: Record; + onlyNewOrgs?: boolean; + footer?: boolean; }; export const campaigns: Map = new Map(); campaigns .set('welcome', { + template: 'card', title: "You've received $VALUE in credits", description: 'Get $VALUE in credits when you upgrade or create an organization with a Pro plan.' }) .set('startup', { + template: 'card', title: 'Welcome to the Startups program!', description: "We're excited to have you on board. Add the coupon code to your Appwrite Pro account to join." }) .set('RenderATL2024', { + template: 'card', title: 'Claim your $100 RenderATL credits', description: 'Get $100 in Cloud credits when you upgrade or create an organization with a Pro plan.' }) .set('dealsfordevs', { + template: 'card', title: 'Claim your $50 Deals For Devs credits', description: 'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan.' + }) + .set('WelcomeManual', { + template: 'card', + title: 'Here is your $VALUE welcome credit!', + description: + 'Upgrade to Appwrite Pro and add the credits to enjoy the full capabilities of Cloud.' + }) + .set('InactiveAccounts', { + template: 'card', + title: 'Get everything out of Cloud. Claim your $VALUE credits.', + description: + 'Get $VALUE in Cloud credits when you upgrade or create an organization with a Pro plan.' + }) + .set('StartupsProgram', { + template: 'review', + title: 'Welcome to the Startups program', + description: + "We're excited to have you on board. Add your credit code to your Appwrite Pro account to join.", + onlyNewOrgs: true, + data: { + cta: 'Get everything out of Cloud with Pro', + claimed: 'Your credits will be valid for 12 months.', + unclaimed: 'Apply your code to join the Startups program.', + reviews: [ + { + name: 'David Foster', + img: '1.jpeg', + desc: 'Managing director', + review: 'We really loved working with Appwrite for launching our bootstrapped "Open Mind" App. It was saving us a lot of money in comparison to Firebase since the amount of users grew quite fast and we needed a quick switch.' + } + ] + } + }) + .set('JSMastery', { + template: 'review', + title: 'Claim your JavaScript Mastery $50 credits.', + description: + 'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan', + data: { + reviews: [ + { + name: 'Marius Bloki', + desc: 'CTO // mySHOEFITTER', + img: 'js_mastery_reviewer_1.png', + review: 'Appwrite has been a tremendous asset in implementing our IT infrastructure. Not only is the software an absolute game-changer, but the team is always there when you need them.' + } + ] + } + }) + .set('FusionVC', { + template: 'review', + title: 'Welcome to Appwrite!', + description: + 'Upgrade to Appwrite Pro and add the credits to enjoy the full capabilities of Cloud. Provided to you by Fusion VC.', + footer: true, + data: { + reviews: [ + { + name: 'David Foster', + img: '1.jpeg', + desc: 'Managing director', + review: 'We really loved working with Appwrite for launching our bootstrapped "Open Mind" App. It was saving us a lot of money in comparison to Firebase since the amount of users grew quite fast and we needed a quick switch.' + } + ] + } + }) + .set('carbon', { + template: 'review', + title: 'Build your entire backend within minutes.', + description: + 'Get $50 in Cloud credits when you upgrade or create an organization with a Pro plan.', + data: { + reviews: [ + { + name: 'David Foster', + img: '1.jpeg', + desc: 'Managing director', + review: 'We really loved working with Appwrite for launching our bootstrapped "Open Mind" App. It was saving us a lot of money in comparison to Firebase since the amount of users grew quite fast and we needed a quick switch.' + } + ] + } }); diff --git a/src/lib/wizards/functions/connectExisting.svelte b/src/lib/wizards/functions/connectExisting.svelte index 7d097f773..f28cc8555 100644 --- a/src/lib/wizards/functions/connectExisting.svelte +++ b/src/lib/wizards/functions/connectExisting.svelte @@ -31,6 +31,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $installation.$id, $repository.id, $choices.branch, diff --git a/src/lib/wizards/functions/createGit.svelte b/src/lib/wizards/functions/createGit.svelte index cf8a4b748..f6307df41 100644 --- a/src/lib/wizards/functions/createGit.svelte +++ b/src/lib/wizards/functions/createGit.svelte @@ -32,6 +32,7 @@ undefined, $createFunction.entrypoint, $createFunction.commands || undefined, + undefined, $installation.$id, $repository.id, $choices.branch, diff --git a/src/lib/wizards/functions/createTemplate.svelte b/src/lib/wizards/functions/createTemplate.svelte index 7d0d4958f..11580051f 100644 --- a/src/lib/wizards/functions/createTemplate.svelte +++ b/src/lib/wizards/functions/createTemplate.svelte @@ -49,6 +49,7 @@ undefined, runtimeDetail.entrypoint, runtimeDetail.commands || undefined, + undefined, $installation.$id, $repository.id, $choices.branch, diff --git a/src/routes/console/apply-credit/+page.svelte b/src/routes/console/apply-credit/+page.svelte index 5db19dea1..d1dd1ce47 100644 --- a/src/routes/console/apply-credit/+page.svelte +++ b/src/routes/console/apply-credit/+page.svelte @@ -67,10 +67,11 @@ let name: string; let coupon: string; let couponData = data?.couponData; + let campaign = campaigns.get(data?.couponData?.campaign ?? data?.campaign); onMount(async () => { await loadPaymentMethods(); - if (!$organizationList?.total) { + if (!$organizationList?.total || campaign?.onlyNewOrgs) { selectedOrgId = newOrgId; } }); @@ -140,7 +141,8 @@ await sdk.forConsole.billing.updateTaxId(org.$id, taxId); } trackEvent(Submit.CreditRedeem, { - coupon: couponData.code + coupon: couponData.code, + campaign: couponData?.campaign }); await invalidate(Dependencies.ORGANIZATION); await goto(`/console/organization-${org.$id}`); @@ -182,7 +184,6 @@ $: isButtonDisabled = checkButtonDisabled(selectedOrgId, name, paymentMethodId) || couponData?.status !== 'active'; - $: campaign = campaigns.get(data?.couponData?.campaign ?? data?.campaign); function checkButtonDisabled(id: string | null, name: string | null, method: string | null) { if (id === newOrgId) { @@ -206,7 +207,7 @@
- {#if $organizationList?.total} + {#if $organizationList?.total && !campaign?.onlyNewOrgs} -
-
-
- promo -

- {#if couponData?.credits} - {campaign.title.replace('VALUE', couponData.credits.toString())} - {:else} - {campaign.title} - {/if} -

+ {#if campaign?.template === 'card'} +
+
+
+ promo +

+ {#if couponData?.credits} + {campaign.title.replace('VALUE', couponData.credits.toString())} + {:else} + {campaign.title} + {/if} +

+
-
+ {/if} {#if selectedOrg?.billingPlan === BillingPlan.PRO}
{:else if selectedOrgId} - +
+ + {#if campaign?.template === 'review' && (campaign?.data?.cta || campaign?.data?.claimed || campaign?.data?.unclaimed)} +
+

{campaign?.data?.cta}

+

+ {#if couponData?.code && couponData?.status === 'active' && campaign?.data?.claimed} + {campaign?.data?.claimed} + {:else if campaign?.data?.unclaimed} + {campaign?.data?.unclaimed} + {/if} +

+
+ {/if} +
+
{/if} diff --git a/src/routes/console/project-[project]/functions/+page.svelte b/src/routes/console/project-[project]/functions/+page.svelte index 989f8ebab..7f45d8302 100644 --- a/src/routes/console/project-[project]/functions/+page.svelte +++ b/src/routes/console/project-[project]/functions/+page.svelte @@ -1,24 +1,31 @@ - {#if $deploymentList?.total} + {#if data?.activeDeployment} {@const activeDeployment = data.activeDeployment}
Active @@ -78,60 +106,7 @@ {/if} {#if activeDeployment} - -
- -
-

Deployment ID

- - - {activeDeployment.$id} - -
-
- - {@const status = activeDeployment.status} - {@const fileSize = humanFileSize(activeDeployment.size)} -
-
-

Build time: {calculateTime(activeDeployment.buildTime)}

-

- Updated: - -

-

Size: {fileSize.value + fileSize.unit}

-

- Source: - -

- {#if $proxyRuleList?.rules?.length} -

- Domains: - -

- {/if} -
-
- - - {activeDeployment.status === 'ready' - ? 'active' - : activeDeployment.status} - - -
-
-
- +
-
-
+ {:else if $deploymentList.total} @@ -201,114 +172,79 @@
{/if} -
- All +
+ All deployments +
+
+ + + +
+ + {#if $tags?.length} +
+
+ + {/if} +
+
+
+
+ +
+
+
+ + + + + + +
{#if $deploymentList.total} -
- - - Deployment ID - Status - Source - Updated - Build Time - Size - - - - {#each $deploymentList.deployments as deployment, index (deployment.$id)} - {@const status = deployment.status} - - - {deployment.$id} - - - {#if activeDeployment?.$id === deployment?.$id} - active - {:else} - - {status} - - {/if} - - - - - - - - - {#if ['processing', 'building'].includes(deployment.status)} - - {:else} - {calculateTime(deployment.buildTime)} - {/if} - - - - {calculateSize(deployment.size)} - - - - - - - { - selectedDeployment = deployment; - showRedeploy = true; - showDropdown = []; - }}> - Redeploy - - {#if deployment.status === 'ready' && deployment.$id !== $func.deployment} - { - selectedDeployment = deployment; - showActivate = true; - showDropdown = []; - }}> - Activate - - {/if} - - Logs - - { - selectedDeployment = deployment; - showDropdown = []; - showDelete = true; - }}> - Delete - - - - - - {/each} - - -
+ + {:else if data?.query} + +
+
+ Sorry we couldn't find any deployments +

There are no deployments that match your filters.

+
+
+ +
+
+
{:else}
@@ -358,7 +294,5 @@ {#if selectedDeployment} - - {/if} diff --git a/src/routes/console/project-[project]/functions/function-[function]/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/+page.ts index 1d85970ce..02b02627d 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/+page.ts +++ b/src/routes/console/project-[project]/functions/function-[function]/+page.ts @@ -1,8 +1,9 @@ import { Query } from '@appwrite.io/console'; import { sdk } from '$lib/stores/sdk'; -import { getLimit, getPage, pageToOffset } from '$lib/helpers/load'; +import { getLimit, getPage, getQuery, pageToOffset } from '$lib/helpers/load'; import { Dependencies, PAGE_LIMIT } from '$lib/constants'; import type { PageLoad } from './$types'; +import { queries, queryParamToMap } from '$lib/components/filters'; export const load: PageLoad = async ({ params, depends, url, route, parent }) => { const data = await parent(); @@ -10,10 +11,14 @@ export const load: PageLoad = async ({ params, depends, url, route, parent }) => const page = getPage(url); const limit = getLimit(url, route, PAGE_LIMIT); const offset = pageToOffset(page, limit); + const query = getQuery(url); + const parsedQueries = queryParamToMap(query || '[]'); + queries.set(parsedQueries); return { offset, limit, + query, activeDeployment: data.function.deployment ? await sdk.forProject.functions.getDeployment( params.function, @@ -23,7 +28,8 @@ export const load: PageLoad = async ({ params, depends, url, route, parent }) => deploymentList: await sdk.forProject.functions.listDeployments(params.function, [ Query.limit(limit), Query.offset(offset), - Query.orderDesc('') + Query.orderDesc(''), + ...parsedQueries.values() ]) }; }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/cancel.svelte b/src/routes/console/project-[project]/functions/function-[function]/cancel.svelte new file mode 100644 index 000000000..77f91bca2 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/cancel.svelte @@ -0,0 +1,49 @@ + + + +

Are you sure you want to cancel this deployment?

+ + + + +
diff --git a/src/routes/console/project-[project]/functions/function-[function]/createManual.svelte b/src/routes/console/project-[project]/functions/function-[function]/createManual.svelte index 91507d198..9e3d33160 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/createManual.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/createManual.svelte @@ -11,10 +11,10 @@ export let show = false; - let active = false; + let active = true; let files: FileList; - let entrypoint: string = null; - let buildCommand: string = null; + let entrypoint: string = $func.entrypoint; + let buildCommand: string = $func.commands; let error: string = null; const functionId = $page.params.function; @@ -31,7 +31,9 @@ ); await invalidate(Dependencies.DEPLOYMENTS); files = undefined; - active = false; + active = true; + entrypoint = $func.entrypoint; + buildCommand = $func.commands; show = false; dispatch('created'); trackEvent(Submit.DeploymentCreate); @@ -43,7 +45,10 @@ $: if (!show) { files = undefined; - active = false; + active = true; + entrypoint = $func.entrypoint; + buildCommand = $func.commands; + show = false; error = null; } @@ -71,13 +76,8 @@ allowedFileExtensions={['gz']} bind:files required={true} /> - - {#if $func.version !== 'v3'} + + {#if $func.version === 'v2'} Build commands now available for functions v3.0 @@ -93,26 +93,35 @@ {:else} - Build settings + Overwrite settings (optional) +

- Overwrite your function configuration for a single deployment or save - commands for future use. + Overwrite your function entrypoint or build commands for a single + deployment or save commands for future use.

+ + + This deployment will be activated after the build is completed. +
{/if} - - This deployment will be activated after the build is completed. - diff --git a/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte index ccaacbe06..4e38f0fbf 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.svelte @@ -1,27 +1,33 @@ - -
- -
-

Deployment ID

- - - {$deployment.$id} - -
-
- - {@const status = $deployment.status} - {@const fileSize = humanFileSize($deployment.size)} -
-
-

- Build time: - {#if ['processing', 'building'].includes($deployment.status)} - - {:else} - {calculateTime($deployment.buildTime)} - {/if} -

-

Updated:

-

- Size: - {fileSize.value + fileSize.unit} -

-

- Source: - -

- {#if $proxyRuleList?.rules?.length} -

- Domains: - -

- {/if} -
-
- - {$deployment.status} - -
+ + +
+ {#if $deployment.status === 'processing'} + + {/if} +
- +
- -
-
-
-
-

Build {$func.name}

- {#if $deployment.status === 'building'} - Building... - {:else} - {$deployment.status} - {/if} -
- -
- - - -
-
-
-
{logs}
+
+
+
+
+

Build {$func.name}

+ {#if $deployment.status === 'building'} + Building... + {:else} + {$deployment.status} + {/if}
-
-
- + +
+ + + +
+ +
+
{logs}
+
+
+
+ + {#if !data.activeDeployment} + + Delete deployment +

+ The deployment will be permanently deleted, including all data associated with it. + This action is irreversible. +

+ + +

Last updated: {toLocaleDateTime($func.$updatedAt)}

+
+
+ + + +
+ {/if} + + + + diff --git a/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.ts index 41afdcff3..bb5cd33b0 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.ts +++ b/src/routes/console/project-[project]/functions/function-[function]/deployment-[deployment]/+page.ts @@ -2,10 +2,17 @@ import { sdk } from '$lib/stores/sdk'; import { Dependencies } from '$lib/constants'; import type { PageLoad } from './$types'; -export const load: PageLoad = async ({ params, depends }) => { +export const load: PageLoad = async ({ params, depends, parent }) => { + const { function: func } = await parent(); depends(Dependencies.DEPLOYMENT); + const deployment = await sdk.forProject.functions.getDeployment( + params.function, + params.deployment + ); + return { - deployment: await sdk.forProject.functions.getDeployment(params.function, params.deployment) + deployment, + activeDeployment: func.deployment === params.deployment }; }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/deploymentCard.svelte b/src/routes/console/project-[project]/functions/function-[function]/deploymentCard.svelte new file mode 100644 index 000000000..693da5950 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/deploymentCard.svelte @@ -0,0 +1,100 @@ + + + +
+ +
+

Deployment ID

+ + + {deployment.$id} + +
+
+ + {@const status = deployment.status} + {@const fileSize = humanFileSize(deployment.size)} +
    +
  • +

    Status

    + + + + +
  • +
  • +

    Build time

    +

    + {calculateTime(deployment.buildTime)} +

    +
  • +
  • +

    Build size

    +

    + {fileSize.value + fileSize.unit} +

    +
  • +
  • +

    Updated

    +

    + +

    +
  • +
+ +
+

Source

+
+ +
+
+ + {#if $proxyRuleList?.rules?.length} +
+

Domains

+ +
+ {/if} +
+ + + + +
+ + diff --git a/src/routes/console/project-[project]/functions/function-[function]/deploymentDomains.svelte b/src/routes/console/project-[project]/functions/function-[function]/deploymentDomains.svelte index 9df7f80cd..68b475340 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/deploymentDomains.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/deploymentDomains.svelte @@ -12,9 +12,10 @@ {domain.rules[0].domain} - +
+ {:else if data?.query} + +
+
+ Sorry we couldn't find any executions +

There are no executions that match your filters.

+
+
+ +
+
+
{:else}
diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/executions/+page.ts index 86ef6c966..2d4d66858 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/executions/+page.ts +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/+page.ts @@ -1,22 +1,29 @@ import { Query } from '@appwrite.io/console'; import { sdk } from '$lib/stores/sdk'; -import { getLimit, getPage, pageToOffset } from '$lib/helpers/load'; +import { getLimit, getPage, getQuery, pageToOffset } from '$lib/helpers/load'; import { Dependencies, PAGE_LIMIT } from '$lib/constants'; import type { PageLoad } from './$types'; +import { queries, queryParamToMap } from '$lib/components/filters'; export const load: PageLoad = async ({ params, depends, url, route }) => { depends(Dependencies.EXECUTIONS); const page = getPage(url); const limit = getLimit(url, route, PAGE_LIMIT); const offset = pageToOffset(page, limit); + const query = getQuery(url); + + const parsedQueries = queryParamToMap(query || '[]'); + queries.set(parsedQueries); return { offset, limit, + query, executions: await sdk.forProject.functions.listExecutions(params.function, [ Query.limit(limit), Query.offset(offset), - Query.orderDesc('') + Query.orderDesc(''), + ...parsedQueries.values() ]) }; }; diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/delete.svelte b/src/routes/console/project-[project]/functions/function-[function]/executions/delete.svelte new file mode 100644 index 000000000..b05f59fb7 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/delete.svelte @@ -0,0 +1,47 @@ + + + +

Are you sure you want to delete this execution?

+ + + + +
diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.svelte new file mode 100644 index 000000000..743aa924d --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.svelte @@ -0,0 +1,381 @@ + + + + Execute function - Appwrite + + + + Execute function + +
+ + {#if func?.version === 'v2'} + + + Customizable execution data now available for functions v3.0 + + Update your function version to make use of new features including customizable + HTTP data in your executions. + + + + + + {:else} + + + + +
+

+ Headers + (optional) + +

+ + + {#if headers} + {#each headers as [name, value], index} + + + + + + + + {/each} + {/if} + + +
+ + + +
  • + + {#if isScheduled} + + + + + {/if} + + {isScheduled + ? `Your function will be executed on ${toLocaleDateTime(dateTime?.toString())}` + : 'Your function will be executed immediately'} + +
  • + {/if} +
    + + + +
    +

    Deployment ID

    + + + {func.deployment} + +
    +
      +
    • +

      Status

      +

      + + active + + +

      +
    • +
    • +

      Build time

      +

      + {#if ['processing', 'building'].includes(deployment.status)} + + {:else} + {calculateTime(deployment.buildTime)} + {/if} +

      +
    • +
    • +

      Size

      +

      + {humanFileSize(deployment.size).value + + humanFileSize(deployment.size).unit} +

      +
    • +
    +
    +

    Source

    + + + +
    +
    +

    Domains

    + + + +
    +
    +

    Updated

    + + + +
    +
    +
    +
    + + + + + +
    diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.ts b/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.ts new file mode 100644 index 000000000..1d11c6734 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/execute-function/+page.ts @@ -0,0 +1,18 @@ +import { sdk } from '$lib/stores/sdk'; +import { Dependencies } from '$lib/constants'; +import type { PageLoad } from './$types'; + +export const load: PageLoad = async ({ params, depends, parent }) => { + const data = await parent(); + depends(Dependencies.DEPLOYMENTS); + + return { + func: data.function, + activeDeployment: data.function.deployment + ? await sdk.forProject.functions.getDeployment( + params.function, + data.function.deployment + ) + : null + }; +}; diff --git a/src/routes/console/project-[project]/functions/function-[function]/executions/table.svelte b/src/routes/console/project-[project]/functions/function-[function]/executions/table.svelte new file mode 100644 index 000000000..2fd33781f --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/executions/table.svelte @@ -0,0 +1,151 @@ + + + + + {#each columns as column} + {#if column.show} + {column.title} + {/if} + {/each} + + + + {#each data.executions.executions as execution, index (execution.$id)} + + {#each columns as column} + {#if column.show} + {#if column.id === '$id'} + {#key column.id} + + {execution.$id} + + {/key} + {:else if column.id === 'status'} + + {@const status = execution.status} +
    + + {#if status === 'scheduled'} + +
    +
    + {:else if column.id === '$createdAt'} + + {timeFromNow(execution.$createdAt)} + + {:else if column.id === 'trigger'} + + + {execution.trigger} + + + {:else if column.id === 'requestMethod'} + + {execution.requestMethod} + + {:else if column.id === 'responseStatusCode'} + + {execution.responseStatusCode} + + {:else if column.id === 'requestPath'} + + {execution.requestPath} + + {:else if column.id === 'duration'} + + {calculateTime(execution.duration)} + + {/if} + {/if} + {/each} + + + + + { + showDropdown = []; + showLogs(execution); + }}> + Logs + + { + selectedExecution = execution; + showDropdown = []; + showDelete = true; + }}> + Delete + + + + +
    + {/each} +
    +
    + +{#if selectedExecution} + +{/if} diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte index db5149a6a..b1b06a033 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/+page.svelte @@ -1,21 +1,23 @@ @@ -28,9 +30,8 @@ + href={`${base}/console/project-${$project.$id}/functions/function-${$func.$id}/executions/execute-function`}> + Execute now + diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/gitConfigurationModal.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/gitConfigurationModal.svelte index 6a8dc10d4..cd43beb40 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/gitConfigurationModal.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/gitConfigurationModal.svelte @@ -64,6 +64,7 @@ $func.logging || undefined, $func.entrypoint, $func.commands || undefined, + $func.scopes || undefined, selectedInstallationId, selectedRepoId, selectedBranch, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateConfiguration.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateConfiguration.svelte index df247fcc8..132520cf3 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateConfiguration.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateConfiguration.svelte @@ -130,6 +130,7 @@ $func.logging || undefined, entrypoint, commands, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, selectedBranch, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte index c2c359bfd..fe63e7726 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateEvents.svelte @@ -46,6 +46,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateLogging.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateLogging.svelte index 2f6e4afb8..59a722f0c 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateLogging.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateLogging.svelte @@ -38,6 +38,7 @@ functionLogging, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateName.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateName.svelte index 8f44fd549..3051debe4 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateName.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateName.svelte @@ -36,6 +36,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updatePermissions.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updatePermissions.svelte index 8af6ef6e3..41a8ecbe3 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updatePermissions.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updatePermissions.svelte @@ -40,6 +40,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte index a4a2f806c..4d9c7da6d 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateRuntime.svelte @@ -46,6 +46,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateSchedule.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateSchedule.svelte index ecd707039..d59ccecf8 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateSchedule.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateSchedule.svelte @@ -36,6 +36,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateScopes.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateScopes.svelte new file mode 100644 index 000000000..a968e3be3 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateScopes.svelte @@ -0,0 +1,90 @@ + + +
    + + Scopes +

    + Select scopes to grant the dynamic key generated temporarily for your function. It is + best practice to allow only necessary permissions. Learn more. +

    + + {#if functionScopes !== null} + + {/if} + + + + + +
    + diff --git a/src/routes/console/project-[project]/functions/function-[function]/settings/updateTimeout.svelte b/src/routes/console/project-[project]/functions/function-[function]/settings/updateTimeout.svelte index c36303279..9c4f07753 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/settings/updateTimeout.svelte +++ b/src/routes/console/project-[project]/functions/function-[function]/settings/updateTimeout.svelte @@ -36,6 +36,7 @@ $func.logging || undefined, $func.entrypoint || undefined, $func.commands || undefined, + $func.scopes || undefined, $func.installationId || undefined, $func.providerRepositoryId || undefined, $func.providerBranch || undefined, diff --git a/src/routes/console/project-[project]/functions/function-[function]/store.ts b/src/routes/console/project-[project]/functions/function-[function]/store.ts index 0bc01a1d4..e5b2bbe56 100644 --- a/src/routes/console/project-[project]/functions/function-[function]/store.ts +++ b/src/routes/console/project-[project]/functions/function-[function]/store.ts @@ -11,8 +11,8 @@ export const proxyRuleList = derived( page, ($page) => $page.data.proxyRuleList as Models.ProxyRuleList ); -export const execute: Writable = writable(); -export const showFunctionExecute: Writable = writable(false); +export const execute: Writable = writable(); //TODO Remove +export const showFunctionExecute: Writable = writable(false); //TODO Remove export const repositories: Writable<{ search: string; diff --git a/src/routes/console/project-[project]/functions/function-[function]/table.svelte b/src/routes/console/project-[project]/functions/function-[function]/table.svelte new file mode 100644 index 000000000..ba7067b68 --- /dev/null +++ b/src/routes/console/project-[project]/functions/function-[function]/table.svelte @@ -0,0 +1,175 @@ + + + + + {#each columns as column} + {#if column.show} + {column.title} + {/if} + {/each} + + + + {#each data.deploymentList.deployments as deployment, index (deployment.$id)} + + {#each columns as column} + {#if column.show} + {#if column.id === '$id'} + {#key column.id} + + {deployment.$id} + + {/key} + {:else if column.id === 'status'} + + {@const status = deployment.status} + {#if data?.activeDeployment?.$id === deployment?.$id} + + + {:else} + + {status} + + {/if} + + {:else if column.id === 'type'} + + + + {:else if column.id === '$updatedAt'} + + + + {:else if column.id === 'buildTime'} + + {#if ['processing', 'building'].includes(deployment.status)} + + {:else} + {calculateTime(deployment.buildTime)} + {/if} + + {:else if column.id === 'size'} + + {calculateSize(deployment.size)} + + {/if} + {/if} + {/each} + + + + + { + selectedDeployment = deployment; + showRedeploy = true; + showDropdown = []; + }}> + Redeploy + + {#if deployment.status === 'ready' && deployment.$id !== $func.deployment} + { + selectedDeployment = deployment; + showActivate = true; + showDropdown = []; + }}> + Activate + + {/if} + + Logs + + {#if deployment.status === 'processing'} + { + selectedDeployment = deployment; + showDropdown = []; + showCancel = true; + }}> + Cancel + + {/if} + { + selectedDeployment = deployment; + showDropdown = []; + showDelete = true; + }}> + Delete + + + + + + {/each} + + + +{#if selectedDeployment} + + + + +{/if} diff --git a/static/icons/dark/color/go.svg b/static/icons/dark/color/go.svg new file mode 100644 index 000000000..ec7ff2412 --- /dev/null +++ b/static/icons/dark/color/go.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/icons/dark/grayscale/go.svg b/static/icons/dark/grayscale/go.svg new file mode 100644 index 000000000..245dc1c89 --- /dev/null +++ b/static/icons/dark/grayscale/go.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/icons/light/color/go.svg b/static/icons/light/color/go.svg new file mode 100644 index 000000000..ec7ff2412 --- /dev/null +++ b/static/icons/light/color/go.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/icons/light/grayscale/go.svg b/static/icons/light/grayscale/go.svg new file mode 100644 index 000000000..245dc1c89 --- /dev/null +++ b/static/icons/light/grayscale/go.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/images/campaigns/FusionVC/footer/dark.png b/static/images/campaigns/FusionVC/footer/dark.png new file mode 100644 index 000000000..6fe0f03b0 Binary files /dev/null and b/static/images/campaigns/FusionVC/footer/dark.png differ diff --git a/static/images/campaigns/FusionVC/footer/light.png b/static/images/campaigns/FusionVC/footer/light.png new file mode 100644 index 000000000..a21263326 Binary files /dev/null and b/static/images/campaigns/FusionVC/footer/light.png differ diff --git a/static/images/campaigns/FusionVC/reviewers/1.jpeg b/static/images/campaigns/FusionVC/reviewers/1.jpeg new file mode 100644 index 000000000..db56c928c Binary files /dev/null and b/static/images/campaigns/FusionVC/reviewers/1.jpeg differ diff --git a/static/images/campaigns/InactiveAccounts/dark.png b/static/images/campaigns/InactiveAccounts/dark.png new file mode 100644 index 000000000..88b548041 Binary files /dev/null and b/static/images/campaigns/InactiveAccounts/dark.png differ diff --git a/static/images/campaigns/InactiveAccounts/light.png b/static/images/campaigns/InactiveAccounts/light.png new file mode 100644 index 000000000..5f4fe3061 Binary files /dev/null and b/static/images/campaigns/InactiveAccounts/light.png differ diff --git a/static/images/campaigns/JSMastery/reviewers/js_mastery_reviewer_1.png b/static/images/campaigns/JSMastery/reviewers/js_mastery_reviewer_1.png new file mode 100644 index 000000000..ce5189b59 Binary files /dev/null and b/static/images/campaigns/JSMastery/reviewers/js_mastery_reviewer_1.png differ diff --git a/static/images/campaigns/StartupsProgram/reviewers/1.jpeg b/static/images/campaigns/StartupsProgram/reviewers/1.jpeg new file mode 100644 index 000000000..db56c928c Binary files /dev/null and b/static/images/campaigns/StartupsProgram/reviewers/1.jpeg differ diff --git a/static/images/campaigns/WelcomeManual/dark.png b/static/images/campaigns/WelcomeManual/dark.png new file mode 100644 index 000000000..88b548041 Binary files /dev/null and b/static/images/campaigns/WelcomeManual/dark.png differ diff --git a/static/images/campaigns/WelcomeManual/light.png b/static/images/campaigns/WelcomeManual/light.png new file mode 100644 index 000000000..5f4fe3061 Binary files /dev/null and b/static/images/campaigns/WelcomeManual/light.png differ diff --git a/static/images/campaigns/carbon/reviewers/1.jpeg b/static/images/campaigns/carbon/reviewers/1.jpeg new file mode 100644 index 000000000..db56c928c Binary files /dev/null and b/static/images/campaigns/carbon/reviewers/1.jpeg differ