Skip to content

Commit cc67c43

Browse files
authored
Merge pull request #292 from wmde/C23_WMDE_Desktop_DE_15
2 parents 595924c + 23313e0 commit cc67c43

39 files changed

+1235
-53
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { createVueApp } from '@src/createVueApp';
2+
3+
import './styles/styles.scss';
4+
5+
import BannerConductor from '@src/components/BannerConductor/FallbackBannerConductor.vue';
6+
import Banner from './components/BannerCtrl.vue';
7+
import FallbackBanner from './components/FallbackBanner.vue';
8+
import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment';
9+
import { WindowResizeHandler } from '@src/utils/ResizeHandler';
10+
import PageWPORG from '@src/page/PageWPORG';
11+
import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki';
12+
import { SkinFactory } from '@src/page/skin/SkinFactory';
13+
import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker';
14+
import TranslationPlugin from '@src/TranslationPlugin';
15+
import { Translator } from '@src/Translator';
16+
import DynamicTextPlugin from '@src/DynamicTextPlugin';
17+
import { LocalImpressionCount } from '@src/utils/LocalImpressionCount';
18+
import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG';
19+
import eventMappings from './event_map';
20+
21+
// Locale-specific imports
22+
import messages from './messages';
23+
import { LocaleFactoryDe } from '@src/utils/LocaleFactory/LocaleFactoryDe';
24+
25+
// Channel specific form setup
26+
import { createFormItems } from './form_items';
27+
import { createFormActions } from '@src/createFormActions';
28+
import { createFallbackDonationLink } from '@src/createFallbackDonationLink';
29+
30+
const localeFactory = new LocaleFactoryDe();
31+
const translator = new Translator( messages );
32+
const mediaWiki = new WindowMediaWiki();
33+
const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 400 ) );
34+
const runtimeEnvironment = new UrlRuntimeEnvironment( window.location );
35+
const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment );
36+
const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment );
37+
38+
const app = createVueApp( BannerConductor, {
39+
page,
40+
bannerConfig: {
41+
delay: runtimeEnvironment.getBannerDelay( 7500 ),
42+
transitionDuration: 1000
43+
},
44+
bannerProps: {
45+
useOfFundsContent: localeFactory.getUseOfFundsLoader().getContent(),
46+
remainingImpressions: impressionCount.getRemainingImpressions( page.getMaxBannerImpressions( 'desktop' ) ),
47+
donationLink: createFallbackDonationLink( page.getTracking(), impressionCount )
48+
},
49+
resizeHandler: new WindowResizeHandler(),
50+
banner: Banner,
51+
fallbackBanner: FallbackBanner,
52+
minWidthForMainBanner: 800,
53+
impressionCount
54+
} );
55+
56+
app.use( TranslationPlugin, translator );
57+
app.use( DynamicTextPlugin, {
58+
campaignParameters: page.getCampaignParameters(),
59+
date: new Date(),
60+
formatters: localeFactory.getFormatters(),
61+
impressionCount,
62+
translator
63+
} );
64+
65+
const currencyFormatter = localeFactory.getCurrencyFormatter();
66+
67+
app.provide( 'currencyFormatter', currencyFormatter );
68+
app.provide( 'formItems', createFormItems( translator, currencyFormatter.euroAmount.bind( currencyFormatter ) ) );
69+
app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount ) );
70+
app.provide( 'tracker', tracker );
71+
72+
app.mount( page.getBannerContainer() );
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { createVueApp } from '@src/createVueApp';
2+
3+
import './styles/styles.scss';
4+
5+
import BannerConductor from '@src/components/BannerConductor/FallbackBannerConductor.vue';
6+
import Banner from './components/BannerVar.vue';
7+
import FallbackBanner from './components/FallbackBanner.vue';
8+
import { UrlRuntimeEnvironment } from '@src/utils/RuntimeEnvironment';
9+
import { WindowResizeHandler } from '@src/utils/ResizeHandler';
10+
import PageWPORG from '@src/page/PageWPORG';
11+
import { WindowMediaWiki } from '@src/page/MediaWiki/WindowMediaWiki';
12+
import { SkinFactory } from '@src/page/skin/SkinFactory';
13+
import { WindowSizeIssueChecker } from '@src/utils/SizeIssueChecker/WindowSizeIssueChecker';
14+
import TranslationPlugin from '@src/TranslationPlugin';
15+
import { Translator } from '@src/Translator';
16+
import DynamicTextPlugin from '@src/DynamicTextPlugin';
17+
import { LocalImpressionCount } from '@src/utils/LocalImpressionCount';
18+
import { LegacyTrackerWPORG } from '@src/tracking/LegacyTrackerWPORG';
19+
import eventMappings from './event_map';
20+
21+
// Locale-specific imports
22+
import messages from './messages';
23+
import { LocaleFactoryDe } from '@src/utils/LocaleFactory/LocaleFactoryDe';
24+
25+
// Channel specific form setup
26+
import { createFormItems } from './form_items';
27+
import { createFormActions } from '@src/createFormActions';
28+
import { createFallbackDonationLink } from '@src/createFallbackDonationLink';
29+
30+
const localeFactory = new LocaleFactoryDe();
31+
const translator = new Translator( messages );
32+
const mediaWiki = new WindowMediaWiki();
33+
const page = new PageWPORG( mediaWiki, ( new SkinFactory( mediaWiki ) ).getSkin(), new WindowSizeIssueChecker( 400 ) );
34+
const runtimeEnvironment = new UrlRuntimeEnvironment( window.location );
35+
const impressionCount = new LocalImpressionCount( page.getTracking().keyword, runtimeEnvironment );
36+
const tracker = new LegacyTrackerWPORG( mediaWiki, page.getTracking().keyword, eventMappings, runtimeEnvironment );
37+
38+
const app = createVueApp( BannerConductor, {
39+
page,
40+
bannerConfig: {
41+
delay: runtimeEnvironment.getBannerDelay( 7500 ),
42+
transitionDuration: 1000
43+
},
44+
bannerProps: {
45+
useOfFundsContent: localeFactory.getUseOfFundsLoader().getContent(),
46+
remainingImpressions: impressionCount.getRemainingImpressions( page.getMaxBannerImpressions( 'desktop' ) ),
47+
donationLink: createFallbackDonationLink( page.getTracking(), impressionCount )
48+
},
49+
resizeHandler: new WindowResizeHandler(),
50+
banner: Banner,
51+
fallbackBanner: FallbackBanner,
52+
minWidthForMainBanner: 800,
53+
impressionCount
54+
} );
55+
56+
app.use( TranslationPlugin, translator );
57+
app.use( DynamicTextPlugin, {
58+
campaignParameters: page.getCampaignParameters(),
59+
date: new Date(),
60+
formatters: localeFactory.getFormatters(),
61+
impressionCount,
62+
translator
63+
} );
64+
65+
const currencyFormatter = localeFactory.getCurrencyFormatter();
66+
67+
app.provide( 'currencyFormatter', currencyFormatter );
68+
app.provide( 'formItems', createFormItems( translator, currencyFormatter.euroAmount.bind( currencyFormatter ) ) );
69+
app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount, { des: '1' } ) );
70+
app.provide( 'tracker', tracker );
71+
72+
app.mount( page.getBannerContainer() );
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<template>
2+
<div class="wmde-banner-wrapper" :class="contentState">
3+
<MainBanner
4+
@form-interaction="$emit( 'bannerContentChanged' )"
5+
v-if="contentState === ContentStates.Main"
6+
:bannerState="bannerState"
7+
>
8+
<template #close-button>
9+
<ButtonClose @close="onCloseMain"/>
10+
</template>
11+
12+
<template #banner-text>
13+
<BannerText/>
14+
</template>
15+
16+
<template #banner-slides="{ play }: any">
17+
<KeenSlider :with-navigation="true" :play="play" :interval="10000" :delay="2000">
18+
19+
<template #slides="{ currentSlide }: any">
20+
<BannerSlides :currentSlide="currentSlide"/>
21+
</template>
22+
23+
</KeenSlider>
24+
</template>
25+
26+
<template #progress>
27+
<ProgressBar amount-to-show-on-right="TARGET"/>
28+
</template>
29+
30+
<template #donation-form="{ formInteraction }: any">
31+
<MultiStepDonation :step-controllers="stepControllers" @form-interaction="formInteraction">
32+
33+
<template #[FormStepNames.MainDonationFormStep]="{ pageIndex, submit, isCurrent, previous }: any">
34+
<MainDonationForm :page-index="pageIndex" @submit="submit" :is-current="isCurrent" @previous="previous"/>
35+
</template>
36+
37+
<template #[FormStepNames.UpgradeToYearlyFormStep]="{ pageIndex, submit, isCurrent, previous }: any">
38+
<UpgradeToYearlyForm :page-index="pageIndex" @submit="submit" :is-current="isCurrent" @previous="previous"/>
39+
</template>
40+
41+
</MultiStepDonation>
42+
</template>
43+
44+
<template #footer>
45+
<FooterAlreadyDonated
46+
@showFundsModal="isFundsModalVisible = true"
47+
@showAlreadyDonatedModal="isAlreadyDonatedModalVisible = true"
48+
/>
49+
</template>
50+
51+
</MainBanner>
52+
53+
<SoftClose
54+
v-if="contentState === ContentStates.SoftClosing"
55+
:show-close-icon="true"
56+
@close="() => onClose( 'SoftClose', CloseChoices.Close )"
57+
@maybeLater="() => onClose( 'SoftClose', CloseChoices.MaybeLater )"
58+
@timeOutClose="() => onClose( 'SoftClose', CloseChoices.TimeOut )"
59+
@maybeLater7Days="() => onClose('SoftClose', CloseChoices.Close)"
60+
/>
61+
62+
<FundsModal
63+
:content="useOfFundsContent"
64+
:is-funds-modal-visible="isFundsModalVisible"
65+
@hideFundsModal="isFundsModalVisible = false"
66+
/>
67+
68+
<AlreadyDonatedModal
69+
:is-visible="isAlreadyDonatedModalVisible"
70+
@hideAlreadyDonatedModal="isAlreadyDonatedModalVisible = false"
71+
@goAway="() => onClose( 'AlreadyDonatedModal', CloseChoices.NoMoreBannersForCampaign )"
72+
@maybeLater="() => onClose( 'AlreadyDonatedModal', CloseChoices.Close )"
73+
>
74+
<template #already-donated-content>
75+
<AlreadyDonatedContent/>
76+
</template>
77+
</AlreadyDonatedModal>
78+
</div>
79+
</template>
80+
81+
<script setup lang="ts">
82+
import { BannerStates } from '@src/components/BannerConductor/StateMachine/BannerStates';
83+
import { ref, watch } from 'vue';
84+
import { UseOfFundsContent as useOfFundsContentInterface } from '@src/domain/UseOfFunds/UseOfFundsContent';
85+
import SoftClose from '@src/components/SoftClose/SoftClose.vue';
86+
import MainBanner from './MainBanner.vue';
87+
import FundsModal from '@src/components/UseOfFunds/FundsModal.vue';
88+
import BannerText from '../content/BannerText.vue';
89+
import BannerSlides from '../content/BannerSlides.vue';
90+
import AlreadyDonatedContent from '../content/AlreadyDonatedContent.vue';
91+
import MultiStepDonation from '@src/components/DonationForm/MultiStepDonation.vue';
92+
import MainDonationForm from '@src/components/DonationForm/Forms/MainDonationForm.vue';
93+
import UpgradeToYearlyForm from '@src/components/DonationForm/Forms/UpgradeToYearlyForm.vue';
94+
import KeenSlider from '@src/components/Slider/KeenSlider.vue';
95+
import { useFormModel } from '@src/components/composables/useFormModel';
96+
import {
97+
createSubmittableMainDonationForm
98+
} from '@src/components/DonationForm/StepControllers/SubmittableMainDonationForm';
99+
import {
100+
createSubmittableUpgradeToYearly
101+
} from '@src/components/DonationForm/StepControllers/SubmittableUpgradeToYearly';
102+
import { CloseChoices } from '@src/domain/CloseChoices';
103+
import { CloseEvent } from '@src/tracking/events/CloseEvent';
104+
import { TrackingFeatureName } from '@src/tracking/TrackingEvent';
105+
import ButtonClose from '@src/components/ButtonClose/ButtonClose.vue';
106+
import ProgressBar from '@src/components/ProgressBar/ProgressBar.vue';
107+
import FooterAlreadyDonated from '@src/components/Footer/FooterAlreadyDonated.vue';
108+
import AlreadyDonatedModal from '@src/components/AlreadyDonatedModal/AlreadyDonatedModal.vue';
109+
110+
enum ContentStates {
111+
Main = 'wmde-banner-wrapper--main',
112+
SoftClosing = 'wmde-banner-wrapper--soft-closing'
113+
}
114+
115+
enum FormStepNames {
116+
MainDonationFormStep = 'MainDonationForm',
117+
UpgradeToYearlyFormStep = 'UpgradeToYearlyForm'
118+
}
119+
120+
interface Props {
121+
bannerState: BannerStates;
122+
useOfFundsContent: useOfFundsContentInterface;
123+
remainingImpressions: number;
124+
}
125+
126+
const props = defineProps<Props>();
127+
const emit = defineEmits( [ 'bannerClosed', 'bannerContentChanged' ] );
128+
129+
const isFundsModalVisible = ref<boolean>( false );
130+
const isAlreadyDonatedModalVisible = ref<boolean>( false );
131+
const contentState = ref<ContentStates>( ContentStates.Main );
132+
const formModel = useFormModel();
133+
const stepControllers = [
134+
createSubmittableMainDonationForm( formModel, FormStepNames.UpgradeToYearlyFormStep ),
135+
createSubmittableUpgradeToYearly( formModel, FormStepNames.MainDonationFormStep, FormStepNames.MainDonationFormStep )
136+
];
137+
138+
watch( contentState, async () => {
139+
emit( 'bannerContentChanged' );
140+
} );
141+
142+
function onCloseMain(): void {
143+
if ( props.remainingImpressions > 0 ) {
144+
contentState.value = ContentStates.SoftClosing;
145+
} else {
146+
onClose( 'MainBanner', CloseChoices.Close );
147+
}
148+
}
149+
150+
function onClose( feature: TrackingFeatureName, userChoice: CloseChoices ): void {
151+
emit( 'bannerClosed', new CloseEvent( feature, userChoice ) );
152+
}
153+
154+
</script>

0 commit comments

Comments
 (0)