diff --git a/packages/api/src/controllers/cloud.js b/packages/api/src/controllers/cloud.js index 407eafcad..ad348b1f7 100644 --- a/packages/api/src/controllers/cloud.js +++ b/packages/api/src/controllers/cloud.js @@ -9,6 +9,8 @@ const { putCloudContent, removeCloudCachedConnection, getPromoWidgetData, + getPromoWidgetList, + getPromoWidgetPreview, } = require('../utility/cloudIntf'); const connections = require('./connections'); const socket = require('../utility/socket'); @@ -296,6 +298,16 @@ module.exports = { return data; }, + promoWidgetList_meta: true, + async promoWidgetList() { + return getPromoWidgetList(); + }, + + promoWidgetPreview_meta: true, + async promoWidgetPreview({ campaign, variant }) { + return getPromoWidgetPreview(campaign, variant); + }, + // chatStream_meta: { // raw: true, // method: 'post', diff --git a/packages/api/src/utility/cloudIntf.js b/packages/api/src/utility/cloudIntf.js index b27880689..b0ea4217a 100644 --- a/packages/api/src/utility/cloudIntf.js +++ b/packages/api/src/utility/cloudIntf.js @@ -480,6 +480,16 @@ async function getPromoWidgetData() { return promoWidgetData; } +async function getPromoWidgetPreview(campaign, variant) { + const resp = await axios.default.get(`${DBGATE_CLOUD_URL}/premium-promo-widget-preview/${campaign}/${variant}`); + return resp.data; +} + +async function getPromoWidgetList() { + const resp = await axios.default.get(`${DBGATE_CLOUD_URL}/promo-widget-list`); + return resp.data; +} + module.exports = { createDbGateIdentitySession, startCloudTokenChecking, @@ -498,4 +508,6 @@ module.exports = { readCloudTestTokenHolder, getPublicIpInfo, getPromoWidgetData, + getPromoWidgetPreview, + getPromoWidgetList, }; diff --git a/packages/web/public/icon-colors.css b/packages/web/public/icon-colors.css index 0e904452d..25cad9a76 100644 --- a/packages/web/public/icon-colors.css +++ b/packages/web/public/icon-colors.css @@ -35,6 +35,11 @@ background: linear-gradient(135deg, #1686c8, #8a25b1); } +.premium-gradient { + background: linear-gradient(135deg, #1686c8, #8a25b1); + color: white; +} + .web-color-primary { background: #1686c8; } diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index cbf82fc72..f2f3872d6 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -8,6 +8,7 @@ import { getCloudSigninTokenHolder, getExtensions, getVisibleToolbar, + promoWidgetPreview, visibleToolbar, visibleWidgetSideBar, } from '../stores'; @@ -50,6 +51,7 @@ import { isProApp } from '../utility/proTools'; import { openWebLink } from '../utility/simpleTools'; import { _t } from '../translations'; import ExportImportConnectionsModal from '../modals/ExportImportConnectionsModal.svelte'; +import { getBoolSettingsValue } from '../settings/settingsTools'; // function themeCommand(theme: ThemeDefinition) { // return { @@ -1164,6 +1166,41 @@ registerCommand({ onClick: () => currentDatabase.set(null), }); +let loadedCampaignList = []; + +registerCommand({ + id: 'internal.loadCampaigns', + category: 'Internal', + name: 'Load campaign list', + testEnabled: () => getBoolSettingsValue('internal.showCampaigns', false), + onClick: async () => { + const resp = await apiCall('cloud/promo-widget-list', {}); + loadedCampaignList = resp; + }, +}); + +registerCommand({ + id: 'internal.showCampaigns', + category: 'Internal', + name: 'Show campaigns', + testEnabled: () => getBoolSettingsValue('internal.showCampaigns', false) && loadedCampaignList?.length > 0, + getSubCommands: () => { + return loadedCampaignList.map(campaign => ({ + text: `${campaign.campaignName} (${campaign.countries || 'Global'}) - #${campaign.quantileRank ?? '*'}/${ + campaign.quantileGroupCount ?? '*' + } - ${campaign.variantIdentifier}`, + onClick: async () => { + promoWidgetPreview.set( + await apiCall('cloud/promo-widget-preview', { + campaign: campaign.campaignIdentifier, + variant: campaign.variantIdentifier, + }) + ); + }, + })); + }, +}); + const electron = getElectron(); if (electron) { electron.addEventListener('run-command', (e, commandId) => runCommand(commandId)); diff --git a/packages/web/src/jsonui/JsonUiContentRenderer.svelte b/packages/web/src/jsonui/JsonUiContentRenderer.svelte index b1562d16d..07fdcb667 100644 --- a/packages/web/src/jsonui/JsonUiContentRenderer.svelte +++ b/packages/web/src/jsonui/JsonUiContentRenderer.svelte @@ -1,22 +1,29 @@ {#each blocks as block, i} {#if block.type in componentMap} - + {/if} {/each} diff --git a/packages/web/src/jsonui/JsonUiCountdown.svelte b/packages/web/src/jsonui/JsonUiCountdown.svelte new file mode 100644 index 000000000..c0e196f05 --- /dev/null +++ b/packages/web/src/jsonui/JsonUiCountdown.svelte @@ -0,0 +1,73 @@ + + +{#if validTo} +
+ Offer ends in:
+ {#each parts as part} + + {part.num} + {part.unit} + + {/each} +
+{/if} + + diff --git a/packages/web/src/jsonui/JsonUiHighlight.svelte b/packages/web/src/jsonui/JsonUiHighlight.svelte new file mode 100644 index 000000000..8437d7a84 --- /dev/null +++ b/packages/web/src/jsonui/JsonUiHighlight.svelte @@ -0,0 +1,19 @@ + + +
+ {text} +
+ + diff --git a/packages/web/src/jsonui/JsonUiMarkdown.svelte b/packages/web/src/jsonui/JsonUiMarkdown.svelte new file mode 100644 index 000000000..cfe522772 --- /dev/null +++ b/packages/web/src/jsonui/JsonUiMarkdown.svelte @@ -0,0 +1,15 @@ + + +
+ +
+ + diff --git a/packages/web/src/stores.ts b/packages/web/src/stores.ts index 6ab382f5e..d30046e99 100644 --- a/packages/web/src/stores.ts +++ b/packages/web/src/stores.ts @@ -187,6 +187,9 @@ export const seenPremiumPromoWidget = writableWithStorage(null, 'seenPremiumProm export const cloudConnectionsStore = writable({}); +export const promoWidgetPreview = writable(null); + + export const DEFAULT_OBJECT_SEARCH_SETTINGS = { pureName: true, schemaName: false, diff --git a/packages/web/src/widgets/AdminPremiumPromoWidget.svelte b/packages/web/src/widgets/AdminPremiumPromoWidget.svelte index d3f80daed..ec3c9ea16 100644 --- a/packages/web/src/widgets/AdminPremiumPromoWidget.svelte +++ b/packages/web/src/widgets/AdminPremiumPromoWidget.svelte @@ -1,14 +1,17 @@ - {#if $promoWidget?.state == 'data'} - + {#if promoWidgetData?.state == 'data'} + {/if} diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte index 5f3c1ff06..052ca4a98 100644 --- a/packages/web/src/widgets/WidgetIconPanel.svelte +++ b/packages/web/src/widgets/WidgetIconPanel.svelte @@ -11,6 +11,7 @@ getCurrentConfig, cloudSigninTokenHolder, seenPremiumPromoWidget, + promoWidgetPreview, } from '../stores'; import mainMenuDefinition from '../../../../app/src/mainMenuDefinition'; import hasPermission from '../utility/hasPermission'; @@ -167,6 +168,8 @@ openWebLink(url, true); } } + + $: promoWidgetData = $promoWidgetPreview || $promoWidget;
@@ -177,7 +180,7 @@ {/if} {#each widgets .filter(x => x && hasPermission(`widgets/${x.name}`)) - .filter(x => !x.isPremiumPromo || (!isProApp() && $promoWidget?.state == 'data')) + .filter(x => !x.isPremiumPromo || (!isProApp() && promoWidgetData?.state == 'data')) // .filter(x => !x.isPremiumOnly || isProApp()) .filter(x => x.name != 'cloud-private' || $cloudSigninTokenHolder) as item}
handleChangeWidget(item.name)} > - {#if item.isPremiumPromo && $promoWidget?.isColoredIcon} + {#if item.isPremiumPromo && promoWidgetData?.isColoredIcon} Premium
- {#if $promoWidget?.identifier != $seenPremiumPromoWidget} + {#if promoWidgetData?.identifier != $seenPremiumPromoWidget}
{/if} {/if}