mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge branch '1.6.x' of github.com:appwrite/console into feat-execution-filter
This commit is contained in:
Generated
+20
@@ -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",
|
||||
@@ -4020,6 +4021,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 +7031,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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -233,6 +233,7 @@ export enum Submit {
|
||||
DeploymentDelete = 'submit_deployment_delete',
|
||||
DeploymentUpdate = 'submit_deployment_update',
|
||||
ExecutionCreate = 'submit_execution_create',
|
||||
ExecutionDelete = 'submit_execution_delete',
|
||||
VariableCreate = 'submit_variable_create',
|
||||
VariableDelete = 'submit_variable_delete',
|
||||
VariableUpdate = 'submit_variable_update',
|
||||
|
||||
@@ -42,9 +42,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{#if couponData.credits >= 100}
|
||||
<p class="inline-tag" use:tooltip={{ content: formatCurrency(couponData.credits) }}>
|
||||
Credits applied
|
||||
</p>
|
||||
<p class="inline-tag">Credits applied</p>
|
||||
{:else}
|
||||
<span class="u-color-text-success">-{formatCurrency(couponData.credits)}</span>
|
||||
{/if}
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="card u-margin-block-start-32 u-flex u-flex-vertical u-gap-8"
|
||||
class="card u-flex u-flex-vertical u-gap-8"
|
||||
style:--p-card-padding="1.5rem"
|
||||
style:--p-card-border-radius="var(--border-radius-small)">
|
||||
<slot />
|
||||
<span class="u-flex u-main-space-between">
|
||||
<p class="text">{currentPlan.name} plan</p>
|
||||
<p class="text">{formatCurrency(currentPlan.price)}</p>
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<div
|
||||
class:input-text-wrapper={!$$slots.default}
|
||||
class:u-flex={$$slots.default}
|
||||
class:u-gap-16={$$slots.default}
|
||||
class:u-gap-8={$$slots.default}
|
||||
class:u-cross-center={$$slots.default}>
|
||||
<input
|
||||
{id}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { Heading } from '$lib/components';
|
||||
import { Avatar, AvatarInitials, Card, Heading } from '$lib/components';
|
||||
import AppwriteLogoDark from '$lib/images/appwrite-logo-dark.svg';
|
||||
import AppwriteLogoLight from '$lib/images/appwrite-logo-light.svg';
|
||||
import LoginDark from '$lib/images/login/login-dark-mode.png';
|
||||
import LoginLight from '$lib/images/login/login-light-mode.png';
|
||||
import type { Coupon } from '$lib/sdk/billing';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { campaigns } from '$lib/stores/campaigns';
|
||||
import { campaigns, type CampaignData } from '$lib/stores/campaigns';
|
||||
import { user } from '$lib/stores/user';
|
||||
|
||||
export const imgLight = LoginLight;
|
||||
@@ -15,8 +15,13 @@
|
||||
export let campaign: string = null;
|
||||
export let coupon: Coupon = null;
|
||||
|
||||
$: variation = coupon?.campaign ?? campaign ? 'card' : 'default';
|
||||
$: selectedCampaign = campaigns.get(coupon?.campaign ?? campaign);
|
||||
$: variation = (coupon?.campaign ?? campaign ? selectedCampaign?.template : 'default') as
|
||||
| 'default'
|
||||
| CampaignData['template'];
|
||||
|
||||
let currentReviewNumber = 0;
|
||||
$: currentReview = selectedCampaign?.data?.reviews?.[currentReviewNumber];
|
||||
|
||||
function generateTitle() {
|
||||
if (coupon?.credits) {
|
||||
@@ -37,17 +42,17 @@
|
||||
|
||||
<main class="grid-1-1 is-full-page" id="main">
|
||||
<section
|
||||
class={`u-flex u-flex-vertical ${variation === 'card' ? 'u-cross-center u-main-center u-height-100-percent u-width-full-line side-bg' : 'side-default'}`}
|
||||
style:--url={variation === 'card'
|
||||
class={`u-flex u-flex-vertical ${variation !== 'default' ? 'u-cross-center u-main-center u-height-100-percent u-width-full-line side-bg' : 'side-default'}`}
|
||||
style:--url={variation !== 'default'
|
||||
? ''
|
||||
: `url(${$app.themeInUse === 'dark' ? imgDark : imgLight})`}>
|
||||
{#if variation === 'card'}
|
||||
{#if variation !== 'default'}
|
||||
<div class="side-bg-container" />
|
||||
{/if}
|
||||
<div
|
||||
class="logo u-flex u-gap-16"
|
||||
class:is-not-mobile={variation === 'default'}
|
||||
class:logo-variation={variation === 'card'}>
|
||||
class:logo-variation={variation !== 'default'}>
|
||||
<a href={user ? '/console' : '/'}>
|
||||
{#if $app.themeInUse === 'dark'}
|
||||
<img
|
||||
@@ -72,15 +77,15 @@
|
||||
<p>Build like a team of hundreds<span class="underscore">_</span></p>
|
||||
</div>
|
||||
{:else if variation === 'card'}
|
||||
<div
|
||||
<section
|
||||
class="u-flex u-flex-vertical u-main-center u-cross-center u-height-100-percent u-width-full-line">
|
||||
<img
|
||||
src={`/images/campaigns/${coupon?.campaign ?? campaign}/${$app.themeInUse}.png`}
|
||||
class="u-block u-image-object-fit-cover side-bg-img"
|
||||
alt="promo" />
|
||||
|
||||
<div class="u-text-center">
|
||||
<div class="is-only-mobile u-width-full-line auth-container">
|
||||
<div class="u-text-center auth-container">
|
||||
<div class="is-only-mobile u-width-full-line">
|
||||
<Heading
|
||||
size="5"
|
||||
tag="h3"
|
||||
@@ -90,7 +95,7 @@
|
||||
{generateTitle()}
|
||||
</Heading>
|
||||
</div>
|
||||
<div class="is-not-mobile u-width-full-line auth-container">
|
||||
<div class="is-not-mobile u-width-full-line">
|
||||
<Heading
|
||||
size="4"
|
||||
tag="h3"
|
||||
@@ -100,11 +105,70 @@
|
||||
{generateTitle()}
|
||||
</Heading>
|
||||
</div>
|
||||
<p class="u-margin-block-start-16 auth-container">
|
||||
<p class="u-margin-block-start-16">
|
||||
{generateDesc()}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{:else if variation === 'review'}
|
||||
<section
|
||||
class="u-flex u-flex-vertical u-main-center u-cross-center u-height-100-percent u-width-full-line review-container">
|
||||
<div class="u-text-center">
|
||||
<div class="is-only-mobile u-width-full-line">
|
||||
<Heading
|
||||
size="5"
|
||||
tag="h3"
|
||||
class="u-margin-block-start-48"
|
||||
trimmed={false}
|
||||
style="font-weight:normal">
|
||||
{generateTitle()}
|
||||
</Heading>
|
||||
</div>
|
||||
<div class="is-not-mobile u-width-full-line">
|
||||
<Heading
|
||||
size="3"
|
||||
tag="h3"
|
||||
class="u-margin-block-start-32"
|
||||
trimmed={false}
|
||||
style="font-weight:normal">
|
||||
{generateTitle()}
|
||||
</Heading>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="body-text-1 u-margin-block-start-16 u-text-center">{generateDesc()}</p>
|
||||
<div class="review-container u-margin-block-start-64">
|
||||
<Card style="--p-card-padding: 1.25rem">
|
||||
<p class="body-text-1">
|
||||
{currentReview.review}
|
||||
</p>
|
||||
<div class="u-margin-block-start-16 u-flex u-gap-16">
|
||||
{#if currentReview?.img}
|
||||
<Avatar
|
||||
src={`/images/campaigns/${coupon?.campaign ?? campaign}/reviewers/${currentReview.img}`}
|
||||
name={currentReview.name}
|
||||
size={40} />
|
||||
{:else}
|
||||
<AvatarInitials size={40} name={currentReview.name} />
|
||||
{/if}
|
||||
<div>
|
||||
<p class="body-text-2 u-bold">{currentReview.name}</p>
|
||||
<p class="body-text-2">{currentReview.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
{#if selectedCampaign?.footer}
|
||||
<div
|
||||
class="u-flex u-gap-16 u-cross-center u-main-center review-footer-container">
|
||||
<p class="u-bold" style:text-transform="uppercase">provided to you by</p>
|
||||
<img
|
||||
style:max-block-size="2.5rem"
|
||||
src={`/images/campaigns/${coupon?.campaign ?? campaign}/footer/${$app.themeInUse}.png`}
|
||||
alt={coupon?.campaign ?? campaign} />
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
{/if}
|
||||
</section>
|
||||
<section class="grid-1-1-col-2 u-flex u-flex-vertical u-cross-center u-main-center">
|
||||
@@ -116,7 +180,7 @@
|
||||
</h1>
|
||||
<h1
|
||||
class="heading-level-5 u-margin-block-start-auto is-only-mobile"
|
||||
class:u-padding-block-start-24={variation === 'card'}>
|
||||
class:u-padding-block-start-24={variation !== 'default'}>
|
||||
<slot name="title" />
|
||||
</h1>
|
||||
<div class="u-margin-block-start-24">
|
||||
@@ -303,6 +367,9 @@
|
||||
.auth-container {
|
||||
max-inline-size: 27.5rem;
|
||||
}
|
||||
.review-container {
|
||||
max-inline-size: 30rem;
|
||||
}
|
||||
.logo-variation {
|
||||
padding-block-start: 2rem;
|
||||
|
||||
@@ -313,4 +380,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.review-footer-container {
|
||||
padding-block-start: 10rem;
|
||||
@media #{$break1} {
|
||||
padding-block-start: 5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,40 +1,119 @@
|
||||
//campaign welcome and startup
|
||||
|
||||
type CampaignData = {
|
||||
export type CampaignData = {
|
||||
title: string;
|
||||
description: string;
|
||||
template: 'card' | 'review';
|
||||
data?: Record<string, unknown>;
|
||||
onlyNewOrgs?: boolean;
|
||||
footer?: boolean;
|
||||
};
|
||||
|
||||
export const campaigns: Map<string, CampaignData> = 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.'
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
@@ -183,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) {
|
||||
@@ -207,7 +207,7 @@
|
||||
<WizardSecondaryContent>
|
||||
<Form bind:this={formComponent} onSubmit={handleSubmit} bind:isSubmitting>
|
||||
<FormList>
|
||||
{#if $organizationList?.total}
|
||||
{#if $organizationList?.total && !campaign?.onlyNewOrgs}
|
||||
<InputSelect
|
||||
bind:value={selectedOrgId}
|
||||
label="Select organization"
|
||||
@@ -254,24 +254,26 @@
|
||||
</FormList>
|
||||
</Form>
|
||||
<svelte:fragment slot="aside">
|
||||
<div
|
||||
class="box card-container u-position-relative"
|
||||
style:--box-border-radius="var(--border-radius-small)">
|
||||
<div class="card-bg"></div>
|
||||
<div class="u-flex u-flex-vertical u-gap-24 u-cross-center u-position-relative">
|
||||
<img
|
||||
src={`/images/campaigns/${data?.couponData?.campaign ?? data?.campaign}/${$app.themeInUse}.png`}
|
||||
class="u-block u-image-object-fit-cover card-img"
|
||||
alt="promo" />
|
||||
<p class="text">
|
||||
{#if couponData?.credits}
|
||||
{campaign.title.replace('VALUE', couponData.credits.toString())}
|
||||
{:else}
|
||||
{campaign.title}
|
||||
{/if}
|
||||
</p>
|
||||
{#if campaign?.template === 'card'}
|
||||
<div
|
||||
class="box card-container u-position-relative"
|
||||
style:--box-border-radius="var(--border-radius-small)">
|
||||
<div class="card-bg"></div>
|
||||
<div class="u-flex u-flex-vertical u-gap-24 u-cross-center u-position-relative">
|
||||
<img
|
||||
src={`/images/campaigns/${data?.couponData?.campaign ?? data?.campaign}/${$app.themeInUse}.png`}
|
||||
class="u-block u-image-object-fit-cover card-img"
|
||||
alt="promo" />
|
||||
<p class="text">
|
||||
{#if couponData?.credits}
|
||||
{campaign.title.replace('VALUE', couponData.credits.toString())}
|
||||
{:else}
|
||||
{campaign.title}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if selectedOrg?.billingPlan === BillingPlan.PRO}
|
||||
<section
|
||||
class="card u-margin-block-start-24"
|
||||
@@ -288,12 +290,27 @@
|
||||
{/if}
|
||||
</section>
|
||||
{:else if selectedOrgId}
|
||||
<EstimatedTotalBox
|
||||
fixedCoupon={!!data?.couponData?.code}
|
||||
billingPlan={BillingPlan.PRO}
|
||||
{collaborators}
|
||||
bind:couponData
|
||||
bind:billingBudget />
|
||||
<div class:u-margin-block-start={campaign?.template === 'card'}>
|
||||
<EstimatedTotalBox
|
||||
fixedCoupon={!!data?.couponData?.code}
|
||||
billingPlan={BillingPlan.PRO}
|
||||
{collaborators}
|
||||
bind:couponData
|
||||
bind:billingBudget>
|
||||
{#if campaign?.template === 'review' && (campaign?.data?.cta || campaign?.data?.claimed || campaign?.data?.unclaimed)}
|
||||
<div class="u-margin-block-end-24">
|
||||
<p class="body-text-1 u-bold">{campaign?.data?.cta}</p>
|
||||
<p class="text u-margin-block-start-8">
|
||||
{#if couponData?.code && couponData?.status === 'active' && campaign?.data?.claimed}
|
||||
{campaign?.data?.claimed}
|
||||
{:else if campaign?.data?.unclaimed}
|
||||
{campaign?.data?.unclaimed}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</EstimatedTotalBox>
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</WizardSecondaryContent>
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { Container, ContainerHeader } from '$lib/layout';
|
||||
import { tooltip } from '$lib/actions/tooltip';
|
||||
import { registerCommands, updateCommandGroupRanks } from '$lib/commandCenter';
|
||||
import { CardContainer, Empty, GridItem1, Id, PaginationWithLimit } from '$lib/components';
|
||||
import { toLocaleDateTime } from '$lib/helpers/date';
|
||||
import { Container, ContainerHeader } from '$lib/layout';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { isServiceLimited } from '$lib/stores/billing';
|
||||
import { marketplace } from '$lib/stores/marketplace.js';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { onMount } from 'svelte';
|
||||
import Initial from '$lib/wizards/functions/cover.svelte';
|
||||
import { registerCommands, updateCommandGroupRanks } from '$lib/commandCenter';
|
||||
import CreateTemplate from '$lib/wizards/functions/createTemplate.svelte';
|
||||
import {
|
||||
templateConfig as templateConfigStore,
|
||||
template as templateStore
|
||||
} from '$lib/wizards/functions/store.js';
|
||||
import { marketplace } from '$lib/stores/marketplace.js';
|
||||
import { parseExpression } from 'cron-parser';
|
||||
import { onMount } from 'svelte';
|
||||
import { functionsList } from './store';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import { isServiceLimited } from '$lib/stores/billing';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -106,7 +107,7 @@
|
||||
aria-hidden="true"
|
||||
use:tooltip={{
|
||||
content: `Next execution:
|
||||
${toLocaleDateTime(func.schedule)}`
|
||||
${toLocaleDateTime(parseExpression(func.schedule, { utc: true }).next().toString())}`
|
||||
}} />
|
||||
</li>
|
||||
{/if}
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<script lang="ts">
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { Submit, trackEvent, trackError } from '$lib/actions/analytics';
|
||||
import { Modal } from '$lib/components';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import { Button } from '$lib/elements/forms';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
// import { sdk } from '$lib/stores/sdk';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
|
||||
export let showDelete = false;
|
||||
export let selectedExecution: Models.Execution = null;
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
// TODO: update SDK to use the new function
|
||||
/// await sdk.forProject.functions.deleteExecution(selectedExecution.$id);
|
||||
await invalidate(Dependencies.FUNCTION);
|
||||
showDelete = false;
|
||||
addNotification({
|
||||
type: 'success',
|
||||
message: `Execution has been deleted`
|
||||
});
|
||||
trackEvent(Submit.ExecutionDelete);
|
||||
} catch (error) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
trackError(error, Submit.ExecutionDelete);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
title="Delete execution"
|
||||
bind:show={showDelete}
|
||||
onSubmit={handleSubmit}
|
||||
icon="exclamation"
|
||||
state="warning"
|
||||
headerDivider={false}>
|
||||
<p data-private>Are you sure you want to delete this execution?</p>
|
||||
<svelte:fragment slot="footer">
|
||||
<Button text on:click={() => (showDelete = false)}>Cancel</Button>
|
||||
<Button secondary submit>Delete</Button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Reference in New Issue
Block a user