vuex#mapState TypeScript Examples

The following examples show how to use vuex#mapState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TaskDetails.ts    From vscode-todo-md with MIT License 5 votes vote down vote up
@Component({
	computed: {
		...mapState(['config', 'selectedTaskLineNumber']),
	},
})
export default class TaskDetails extends Vue {
	config!: ExtensionConfig['webview'];
	selectedTaskLineNumber!: number;

	inputValue = '';

	$refs!: {
		detailsTaskTitle: HTMLTextAreaElement;
	};

	updateInputValueBasedOnSelectedTask() {
		this.inputValue = getTaskAtLineWebview(this.selectedTaskLineNumber)?.rawText || '';
	}

	onTaskTitleChange(event: Event) {
		this.inputValue = (event.target as HTMLTextAreaElement).value;
		this.resizeTaskTitleTextarea();
		this.editSelectedTask();
	}
	/**
	 * Resize textarea to fit the text (or compress to 1 line height)
	 */
	resizeTaskTitleTextarea() {
		setTimeout(() => {
			this.$refs.detailsTaskTitle.style.height = 'auto';
			this.$refs.detailsTaskTitle.style.height = `${this.$refs.detailsTaskTitle.scrollHeight}px`;
		}, 0);
	}
	editSelectedTask = debounce(function() {
		// @ts-ignore
		if (this.inputValue) {
			// @ts-ignore
			SendMessage.editRawText(this.selectedTaskLineNumber, this.inputValue);
		}
	}, 500);

	@Watch('selectedTaskLineNumber')
	selectedTaskChanged() {
		this.updateInputValueBasedOnSelectedTask();
		this.resizeTaskTitleTextarea();
	}

	mounted() {
		this.updateInputValueBasedOnSelectedTask();
		setTimeout(() => {
			this.resizeTaskTitleTextarea();
		}, 100);
	}
}
Example #2
Source File: App.ts    From vscode-todo-md with MIT License 4 votes vote down vote up
// needs to be global for recursive rendering

@Component({
	components: {
		VueContext,
		TaskDetails: async () => import('./components/TaskDetails.vue'),
	},
	computed: {
		...mapState(['tasksAsTree', 'filterInputValue', 'config', 'defaultFileSpecified', 'activeDocumentOpened', 'selectedTaskLineNumber']),
		...mapGetters(['filteredSortedTasks', 'autocompleteItems']),
	},
})
export default class App extends Vue {
	tasksAsTree!: TheTask[];
	filteredSortedTasks!: TheTask[];
	filterInputValue!: string;
	config!: ExtensionConfig['webview'];
	defaultFileSpecified!: boolean;
	activeDocumentOpened!: boolean;
	autocompleteItems!: any;
	/**
	 * `-1` When no task is selected.
	 */
	selectedTaskLineNumber!: number;
	/**
	 * Task rename modal input value
	 */
	newTaskTitle = '';

	contextMenuTask!: TheTask;

	filteredSuggestions: {
		data: string[];
	}[] = [];
	isSuggestVisible = false;
	/**
	 * Hack to prevent keydown event opening suggest
	 */
	shouldHideSuggest = false;
	shouldRevokeAutoShowSuggest = false;

	showNotification = SendMessage.showNotification;

	taskDetailsManuallyTriggered = false;

	get taskDetailsVisible() {
		return (this.config.showTaskDetails || this.taskDetailsManuallyTriggered) && this.selectedTaskLineNumber !== -1;
	}

	$refs!: {
		autosuggest: any;
		taskContextMenu: any;
		newTaskText: HTMLInputElement;
		taskDetails: TaskDetails;
	};
	// ──────────────────────────────────────────────────────────────────────
	/**
	 * Highlight filter matches for single autocomplete item
	 */
	fuzzyHighlight(value: string) {
		return fuzzysort.highlight(fuzzysort.single(this.filterInputValue, value) || undefined, '<mark>', '</mark>');
	}
	/**
	 * Open autocomplete on Ctrl+Space
	 */
	openSuggest() {
		if (!this.config.autoShowSuggest) {
			this.config.autoShowSuggest = true;
			this.shouldRevokeAutoShowSuggest = true;
		}
		this.shouldHideSuggest = false;
	}
	onOpenedSuggest() {
		this.isSuggestVisible = true;
	}
	onClosedSuggest() {
		this.isSuggestVisible = false;
		if (this.shouldRevokeAutoShowSuggest) {
			this.config.autoShowSuggest = false;
			this.shouldRevokeAutoShowSuggest = false;
		}
	}
	/**
	 * Event that is fired when typing in filter input
	 */
	onFilterInputChange(value: string) {
		this.shouldHideSuggest = false;
		selectTaskMutation(-1);
		updateFilterValueMutation(value);
		this.filteredSuggestions = [{
			data: fuzzysort.go(value, this.autocompleteItems[0].data).map(item => item.target),
		}];
		Vue.nextTick(() => {
			this.$refs.autosuggest.setCurrentIndex(0);
			this.selectFirstTask();
		});
		this.updateWebviewCounter(this.filteredSortedTasks.length);
	}
	onFilterChangeDebounced = debounce(this.onFilterInputChange, 100);
	/**
	 * Event fired when accepting autocomplete suggestions
	 */
	onSelected(e: { item: string }) {
		if (e) {
			this.onFilterInputChange(e.item);
			App.focusFilterInput();
		}
	}
	/**
	 * Handle Tab keypress as Autocomplete accept suggestion
	 * (only when autocomplete is visible)
	 */
	tabHandler(e: KeyboardEvent) {
		const { listeners, setCurrentIndex, setChangeItem, getItemByIndex } = this.$refs.autosuggest;
		const item = getItemByIndex(this.$refs.autosuggest.currentIndex);
		if (!item) {
			return;
		}
		e.preventDefault();
		setChangeItem(item, true);
		this.$refs.autosuggest.loading = true;
		listeners.selected(true);
	}
	async downHandler(e: KeyboardEvent) {
		if (!this.filteredSuggestions.length || this.filteredSuggestions[0].data[0] === this.filterInputValue || !this.isSuggestVisible) {
			this.shouldHideSuggest = true;
			const selectedTaskLineNumber = await selectNextTaskAction();
			if (selectedTaskLineNumber && !this.isSuggestVisible) {
				this.scrollIntoView(selectedTaskLineNumber);
				e.preventDefault();
			}
			return;
		}
	}
	async upHandler(e: KeyboardEvent) {
		if (!this.filteredSuggestions.length || this.filteredSuggestions[0].data[0] === this.filterInputValue || !this.isSuggestVisible) {
			const selectedTaskLineNumber = await selectPrevTaskAction();
			if (selectedTaskLineNumber && !this.isSuggestVisible) {
				this.scrollIntoView(selectedTaskLineNumber);
				e.preventDefault();
			}
			return;
		}
	}
	deleteTask() {
		SendMessage.deleteTask(this.contextMenuTask.lineNumber);
	}
	revealTask() {
		SendMessage.revealTask(this.contextMenuTask.lineNumber);
	}
	startTask() {
		SendMessage.startTask(this.contextMenuTask.lineNumber);
	}
	setDueDate() {
		SendMessage.setDueDate(this.contextMenuTask.lineNumber);
	}
	onTaskListScroll() {
		this.$refs.taskContextMenu.close();
	}
	// ──────────────────────────────────────────────────────────────────────
	selectFirstTask() {
		const firstTask = this.filteredSortedTasks[0];
		if (firstTask) {
			selectTaskMutation(firstTask.lineNumber);
		}
	}
	updateWebviewCounter(numberOfTasks: number) {
		SendMessage.updateWebviewTitle(numberOfTasks);
	}
	static focusFilterInput() {
		Vue.nextTick(() => {
			const suggest = document.getElementById('autosuggest__input');
			if (suggest) {
				suggest.focus();
			}
		});
	}
	focusFilterInput = App.focusFilterInput;
	scrollIntoView(lineNumber: number) {
		const element = document.getElementById(`ln${lineNumber}`);
		// @ts-ignore https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded
		element.scrollIntoViewIfNeeded(false);
	}
	// ──────────────────────────────────────────────────────────────────────
	mounted() {
		SendMessage.webviewLoaded();

		App.focusFilterInput();
		window.addEventListener('focus', App.focusFilterInput);
		setTimeout(() => {
			this.selectFirstTask();
		}, 100);

		this.$root.$on(VueEvents.openTaskContextMenu, (data: {e: MouseEvent; task: TheTask}) => {
			this.contextMenuTask = data.task;
			this.$refs.taskContextMenu.open(data.e);
		});
		this.$root.$on(VueEvents.focusFilterInput, () => {
			App.focusFilterInput();
		});

		window.addEventListener('click', e => {
			const link = (e.target as HTMLElement).closest('a');
			if (link && link.dataset.href) {
				SendMessage.followLink(link.dataset.href);
			}
		});

		window.addEventListener('keydown', e => {
			if (e.key === 'ArrowRight') {
				SendMessage.toggleTaskCollapse(this.selectedTaskLineNumber);
			} else if (e.key === 'Delete' && e.shiftKey) {
				if (this.selectedTaskLineNumber !== -1) {
					SendMessage.deleteTask(this.selectedTaskLineNumber);
				}
			} else if (e.key === 'Escape') {
				selectTaskMutation(-1);
				this.taskDetailsManuallyTriggered = false;
				this.focusFilterInput();
			} else if (e.key === 'd' && e.altKey) {
				const task = getTaskAtLineWebview(this.selectedTaskLineNumber);
				if (task) {
					toggleDoneMutation(task);
				}
			} else if (e.key === 'F2') {
				this.taskDetailsManuallyTriggered = true;
				setTimeout(() => {
					this.$refs.taskDetails.$refs.detailsTaskTitle.focus();
				}, 100);
			}
		});
	}
}
Example #3
Source File: Task.ts    From vscode-todo-md with MIT License 4 votes vote down vote up
@Component({
	computed: {
		...mapState(['config', 'filterInputValue', 'selectedTaskLineNumber']),
	},
	components: {
		TaskTitle: TaskTitleComponent,
	},
})
export default class Task extends Vue {
	@Prop()
	private readonly model!: TheTask;

	config!: ExtensionConfig['webview'];
	filterInputValue!: string;
	selectedTaskLineNumber!: number;

	duration = this.model.duration ? this.model.duration :
		this.model.start ? durationTo(this.model, false, !this.model.done) : '';// TODO: respect `durationIncludeSeconds`
	durationTimerId: any;

	toggleTaskCollapse = () => {
		SendMessage.toggleTaskCollapse(this.model.lineNumber);
	};
	toggleTaskCollapseRecursive = () => {
		SendMessage.toggleTaskCollapseRecursive(this.model.lineNumber);
	};
	// ──────────────────────────────────────────────────────────────────────
	openTaskContextMenu(e: MouseEvent, task: TheTask) {
		selectTaskMutation(task.lineNumber);
		this.$root.$emit(VueEvents.openTaskContextMenu, {
			e,
			task,
		});
	}
	selectThisTask() {
		selectTaskMutation(this.model.lineNumber);
		this.$root.$emit(VueEvents.focusFilterInput);
	}
	toggleDone() {
		toggleDoneMutation(this.model);
	}
	revealTask() {
		SendMessage.revealTask(this.model.lineNumber);
	}
	incrementCount() {
		SendMessage.incrementCount(this.model.lineNumber);
	}
	decrementCount() {
		SendMessage.decrementCount(this.model.lineNumber);
	}
	// ──────────────────────────────────────────────────────────────────────
	/**
	 * Computed classes assigned to `task` element
	 */
	get classes() {
		const classMap: Record<string, boolean> = {};
		classMap['task--done'] = this.model.done;
		if (this.model.parentTaskLineNumber !== undefined) {
			classMap[`task--nested-lvl-${this.model.indentLvl}`] = true;
		}
		if (this.config.showPriority) {
			switch (this.model.priority) {
				case 'A': classMap['task--priA'] = true; break;
				case 'B': classMap['task--priB'] = true; break;
				case 'C': classMap['task--priC'] = true; break;
				case 'D': classMap['task--priD'] = true; break;
				case 'E': classMap['task--priE'] = true; break;
				case 'F': classMap['task--priF'] = true; break;
			}
		}
		if (this.model.due) {
			switch (this.model.due.isDue) {
				case DueState.NotDue: classMap.notDue = true;break;
				case DueState.Due: classMap.due = true;break;
				case DueState.Overdue: classMap.overdue = true;break;
				case DueState.Invalid: classMap.invalid = true;break;
			}
		}
		if (this.config.completedStrikeThrough) {
			classMap['task--strike-through'] = true;
		}
		if (this.selectedTaskLineNumber === this.model.lineNumber) {
			classMap['task--selected'] = true;
		}
		return classMap;
	}
	get dueDate() {
		if (this.model.due?.isDue === undefined || this.model.done) {
			return undefined;
		} else {
			const dueClasses: string[] = ['task__due-state'];
			let dueText = '';
			let dueTitle = '';
			switch (this.model.due.isDue) {
				case DueState.NotDue: {
					dueClasses.push('task__due-state--not-due');
					dueText = `<span class="codicon codicon-milestone"></span><span class="task__days-to-count">${this.model.due.closestDueDateInTheFuture}</span>`;
					dueTitle = `In ${this.model.due.daysUntilDue} days`;
					break;
				}
				case DueState.Due: {
					dueClasses.push('task__due-state--due');
					dueText = '<span class="codicon codicon-history"></span>';
					dueTitle = `Due Today`;
					break;
				}
				case DueState.Overdue: {
					dueClasses.push('task__due-state--overdue');
					dueText = `<span class="codicon codicon-history"></span><span class="task__overdue-count">${this.model.due?.overdueInDays || ''}</span>`;
					dueTitle = `Overdue by ${this.model.due?.overdueInDays || '?'} days`;
					break;
				}
				case DueState.Invalid: {
					dueClasses.push('task__due-state--invalid');
					dueText = '<span class="codicon codicon-error"></span><span class="task__days-to-count">Invalid</span>';
					dueTitle = 'Due date is Invalid';
					break;
				}
			}
			return `<span class="${dueClasses.join(' ')}" title="${dueTitle} \n\n ${this.model.due.raw}">${dueText}</span>`;
		}
	}
	get nestedCount() {
		if (this.model.subtasks.length !== 0 && this.model.parentTaskLineNumber === undefined) {
			const allNestedTasks = getAllNestedTasksWebview(this.model);
			return `<span class="task__nested-count-number" title="Nested tasks count">${allNestedTasks.filter(task => task.done).length}/${allNestedTasks.length}</span>`;
		} else {
			return undefined;
		}
	}

	mounted() {
		if (!this.model.duration && this.model.start && !this.model.done) {
			this.durationTimerId = setInterval(() => {
				this.duration = durationTo(this.model, false, true);
			}, 1000);
		}
	}
	beforeUnmount() {
		clearInterval(this.durationTimerId);
	}
}
Example #4
Source File: TaskTitle.ts    From vscode-todo-md with MIT License 4 votes vote down vote up
@Component({
	computed: {
		...mapState(['config', 'filterInputValue']),
	},
})
export default class TaskTitle extends Vue {
	@Prop(String) readonly stuff!: string;

	config!: ExtensionConfig['webview'];
	filterInputValue!: string;

	// ──────────────────────────────────────────────────────────────────────
	updateFilterValue(e: MouseEvent) {
		// @ts-ignore
		const newValue: string | undefined = e.target?.innerText;
		if (!newValue) {
			return;
		}
		if (e.ctrlKey) {
			updateFilterValueMutation(`${this.filterInputValue} ${newValue}`);
		} else {
			updateFilterValueMutation(newValue);
		}
		this.$root.$emit(VueEvents.focusFilterInput);
	}
	styleForTag(tag: string) {
		if (tag in this.config.tagStyles) {
			return this.config.tagStyles[tag];
		}
		return undefined;
	}
	// ──────────────────────────────────────────────────────────────────────
	render(h: CreateElement) {
		const returnEl = h('span', {}, []);
		const words = this.stuff.split(' ');

		const currentWords = [];

		for (const word of words) {
			if (
				word.length > 1 &&
				(word[0] === '#' || word[0] === '+' || word[0] === '@')
			) {
				const currentWordsAsText = `${currentWords.join(' ')} `;
				currentWords.length = 0;
				returnEl.children?.push(h('span', {
					domProps: {
						innerHTML: marked(currentWordsAsText),
					},
				}));

				let style;
				if (word[0] === '#') {
					style = this.styleForTag(word.slice(1));
				}

				returnEl.children?.push(h('span', {
					class: word[0] === '#' ? 'task__tag' : word[0] === '+' ? 'task__project' : 'task__context',
					style,
					domProps: {
						innerText: word,
					},
					on: {
						click: this.updateFilterValue,
					},
				}));

				returnEl.children?.push(h('span', ' '));
			} else {
				currentWords.push(word);
			}
		}

		const currentWordsAsText = currentWords.join(' ');

		returnEl.children?.push(h('span', {
			domProps: {
				innerHTML: marked(currentWordsAsText),
			},
		}));

		return returnEl;
	}
}
Example #5
Source File: Search.ts    From vue-storefront-1 with MIT License 4 votes vote down vote up
Search = {
  name: 'SearchPanel',
  data () {
    return {
      products: [],
      search: '',
      size: 18,
      start: 0,
      placeholder: i18n.t('Type what you are looking for...'),
      emptyResults: false,
      readMore: true,
      componentLoaded: false
    }
  },
  mounted () {
    this.search = localStorage.getItem(`shop/user/searchQuery`) || ''

    if (this.search) {
      this.makeSearch();
    }
  },
  beforeDestroy () {
    localStorage.setItem(`shop/user/searchQuery`, this.search ? this.search : '');
  },
  methods: {
    onEscapePress () {
      this.closeSearchpanel()
    },
    closeSearchpanel () {
      this.$store.commit('ui/setSidebar', false)
      this.$store.commit('ui/setMicrocart', false)
      this.$store.commit('ui/setSearchpanel', false)
    },
    buildSearchQuery (queryText) {
      let searchQuery = prepareQuickSearchQuery(queryText)
      return searchQuery
    },
    async makeSearch () {
      if (this.search !== '' && this.search !== undefined) {
        let query = this.buildSearchQuery(this.search)
        let startValue = 0;
        this.start = startValue
        this.readMore = true
        try {
          const { items } = await this.$store.dispatch('product/findProducts', {
            query,
            start: this.start,
            size: this.size,
            options: {
              populateRequestCacheTags: false,
              prefetchGroupProducts: false
            }
          })
          this.products = items
          this.start = startValue + this.size
          this.emptyResults = items.length < 1
        } catch (err) {
          Logger.error(err, 'components-search')()
        }
      } else {
        this.products = []
        this.emptyResults = 0
      }
    },
    async seeMore () {
      if (this.search !== '' && this.search !== undefined) {
        let query = this.buildSearchQuery(this.search)
        let startValue = this.start;
        try {
          const { items, total, start } = await this.$store.dispatch('product/findProducts', {
            query,
            start: startValue,
            size: this.size,
            options: {
              populateRequestCacheTags: false,
              prefetchGroupProducts: false
            }
          })
          let page = Math.floor(total / this.size)
          let exceeed = total - this.size * page
          if (start === total - exceeed) {
            this.readMore = false
          }
          this.products = this.products.concat(items)
          this.start = startValue + this.size
          this.emptyResults = this.products.length < 1
        } catch (err) {
          Logger.error(err, 'components-search')()
        }
      } else {
        this.products = []
        this.emptyResults = 0
      }
    }
  },
  computed: {
    items () {
      return this.$store.state.search
    },
    ...mapState({
      isOpen: (state: RootState) => state.ui.searchpanel
    })
  },
  mixins: [onEscapePress]
}
Example #6
Source File: Payment.ts    From vue-storefront-1 with MIT License 4 votes vote down vote up
Payment = {
  name: 'Payment',
  props: {
    isActive: {
      type: Boolean,
      required: true
    }
  },
  data () {
    return {
      isFilled: false,
      countries: Countries,
      payment: this.$store.getters['checkout/getPaymentDetails'],
      generateInvoice: false,
      sendToShippingAddress: false,
      sendToBillingAddress: false
    }
  },
  computed: {
    ...mapState({
      currentUser: (state: RootState) => state.user.current,
      shippingDetails: (state: RootState) => state.checkout.shippingDetails
    }),
    ...mapGetters({
      paymentMethods: 'checkout/getPaymentMethods',
      paymentDetails: 'checkout/getPaymentDetails',
      isVirtualCart: 'cart/isVirtualCart'
    })
  },
  created () {
    if (!this.payment.paymentMethod || this.notInMethods(this.payment.paymentMethod)) {
      this.payment.paymentMethod = this.paymentMethods.length > 0 ? this.paymentMethods[0].code : 'cashondelivery'
    }
  },
  beforeMount () {
    this.$bus.$on('checkout-after-load', this.onCheckoutLoad)
  },
  mounted () {
    if (this.payment.firstName) {
      this.initializeBillingAddress()
    } else {
      if (this.payment.company) {
        this.generateInvoice = true
      }
    }
    this.changePaymentMethod()
  },
  beforeDestroy () {
    this.$bus.$off('checkout-after-load', this.onCheckoutLoad)
  },
  watch: {
    shippingDetails: {
      handler () {
        if (this.sendToShippingAddress) {
          this.copyShippingToBillingAddress()
        }
      },
      deep: true
    },
    sendToShippingAddress: {
      handler () {
        this.useShippingAddress()
      }
    },
    sendToBillingAddress: {
      handler () {
        this.useBillingAddress()
      }
    },
    generateInvoice: {
      handler () {
        this.useGenerateInvoice()
      }
    },
    paymentMethods: {
      handler: debounce(function () {
        this.changePaymentMethod()
      }, 500)
    }
  },
  methods: {
    sendDataToCheckout () {
      this.$bus.$emit('checkout-after-paymentDetails', this.payment, this.$v)
      this.isFilled = true
    },
    edit () {
      if (this.isFilled) {
        this.$bus.$emit('checkout-before-edit', 'payment')
      }
    },
    hasBillingData () {
      if (this.currentUser) {
        if (this.currentUser.hasOwnProperty('default_billing')) {
          return true
        }
      }
      return false
    },
    initializeBillingAddress () {
      let initialized = false
      if (this.currentUser) {
        if (this.currentUser.hasOwnProperty('default_billing')) {
          let id = this.currentUser.default_billing
          let addresses = this.currentUser.addresses
          for (let i = 0; i < addresses.length; i++) {
            if (toString(addresses[i].id) === toString(id)) {
              this.payment = {
                firstName: addresses[i].firstname,
                lastName: addresses[i].lastname,
                company: addresses[i].company,
                country: addresses[i].country_id,
                state: addresses[i].region.region ? addresses[i].region.region : '',
                city: addresses[i].city,
                streetAddress: addresses[i].street[0],
                apartmentNumber: addresses[i].street[1],
                zipCode: addresses[i].postcode,
                taxId: addresses[i].vat_id,
                phoneNumber: addresses[i].telephone,
                paymentMethod: this.paymentMethods[0].code
              }
              this.generateInvoice = true
              this.sendToBillingAddress = true
              initialized = true
            }
          }
        }
      }
      if (!initialized) {
        this.payment = this.paymentDetails || {
          firstName: '',
          lastName: '',
          company: '',
          country: '',
          state: '',
          city: '',
          streetAddress: '',
          apartmentNumber: '',
          postcode: '',
          zipCode: '',
          phoneNumber: '',
          taxId: '',
          paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : ''
        }
      }
    },
    useShippingAddress () {
      if (this.sendToShippingAddress) {
        this.copyShippingToBillingAddress()
        this.sendToBillingAddress = false
      }

      if (!this.sendToBillingAddress && !this.sendToShippingAddress) {
        this.payment = this.paymentDetails
      }
    },
    copyShippingToBillingAddress () {
      this.payment = {
        firstName: this.shippingDetails.firstName,
        lastName: this.shippingDetails.lastName,
        country: this.shippingDetails.country,
        state: this.shippingDetails.state,
        city: this.shippingDetails.city,
        streetAddress: this.shippingDetails.streetAddress,
        apartmentNumber: this.shippingDetails.apartmentNumber,
        zipCode: this.shippingDetails.zipCode,
        phoneNumber: this.shippingDetails.phoneNumber,
        paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : ''
      }
    },
    useBillingAddress () {
      if (this.sendToBillingAddress) {
        let id = this.currentUser.default_billing
        let addresses = this.currentUser.addresses
        for (let i = 0; i < addresses.length; i++) {
          if (toString(addresses[i].id) === toString(id)) {
            this.payment = {
              firstName: addresses[i].firstname,
              lastName: addresses[i].lastname,
              company: addresses[i].company,
              country: addresses[i].country_id,
              state: addresses[i].region.region ? addresses[i].region.region : '',
              city: addresses[i].city,
              streetAddress: addresses[i].street[0],
              apartmentNumber: addresses[i].street[1],
              zipCode: addresses[i].postcode,
              taxId: addresses[i].vat_id,
              phoneNumber: addresses[i].telephone,
              paymentMethod: this.paymentMethods.length > 0 ? this.paymentMethods[0].code : ''
            }
            this.generateInvoice = true
          }
        }
        this.sendToShippingAddress = false
      }

      if (!this.sendToBillingAddress && !this.sendToShippingAddress) {
        this.payment = this.paymentDetails
        this.generateInvoice = false
      }
    },
    useGenerateInvoice () {
      if (!this.generateInvoice) {
        this.payment.company = ''
        this.payment.taxId = ''
      }
    },
    getCountryName () {
      for (let i = 0; i < this.countries.length; i++) {
        if (this.countries[i].code === this.payment.country) {
          return this.countries[i].name
        }
      }
      return ''
    },
    getPaymentMethod () {
      for (let i = 0; i < this.paymentMethods.length; i++) {
        if (this.paymentMethods[i].code === this.payment.paymentMethod) {
          return {
            title: this.paymentMethods[i].title ? this.paymentMethods[i].title : this.paymentMethods[i].name
          }
        }
      }
      return {
        name: ''
      }
    },
    notInMethods (method) {
      let availableMethods = this.paymentMethods
      if (availableMethods.find(item => item.code === method)) {
        return false
      }
      return true
    },
    changePaymentMethod () {
      // reset the additional payment method component container if exists.
      if (document.getElementById('checkout-order-review-additional-container')) {
        document.getElementById('checkout-order-review-additional-container').innerHTML = '<div id="checkout-order-review-additional">&nbsp;</div>' // reset
      }

      // Let anyone listening know that we've changed payment method, usually a payment extension.
      if (this.payment.paymentMethod) {
        this.$bus.$emit('checkout-payment-method-changed', this.payment.paymentMethod)
      }
    },
    changeCountry () {
      this.$store.dispatch('checkout/updatePaymentDetails', { country: this.payment.country })
      this.$store.dispatch('cart/syncPaymentMethods', { forceServerSync: true })
    },
    onCheckoutLoad () {
      this.payment = this.$store.getters['checkout/getPaymentDetails']
    }
  }
}
Example #7
Source File: PersonalDetails.ts    From vue-storefront-1 with MIT License 4 votes vote down vote up
PersonalDetails = {
  name: 'PersonalDetails',
  props: {
    isActive: {
      type: Boolean,
      required: true
    },
    focusedField: {
      type: String,
      required: false
    }
  },
  data () {
    return {
      isFilled: false,
      personalDetails: this.$store.state.checkout.personalDetails,
      createAccount: false,
      acceptConditions: false,
      password: '',
      rPassword: '',
      isValidationError: false
    }
  },
  computed: {
    ...mapState({
      currentUser: (state: RootState) => state.user.current
    }),
    ...mapGetters({
      isVirtualCart: 'cart/isVirtualCart'
    })
  },
  methods: {
    onLoggedIn (receivedData) {
      this.personalDetails = {
        firstName: receivedData.firstname,
        lastName: receivedData.lastname,
        emailAddress: receivedData.email
      }
    },
    sendDataToCheckout () {
      if (this.createAccount) {
        this.personalDetails.password = this.password
        this.personalDetails.createAccount = true
      } else {
        this.personalDetails.createAccount = false
      }
      this.$bus.$emit('checkout-after-personalDetails', this.personalDetails, this.$v)
      this.isFilled = true
      this.isValidationError = false
    },
    edit () {
      if (this.isFilled) {
        this.$bus.$emit('checkout-before-edit', 'personalDetails')
      }
    },
    gotoAccount () {
      this.$bus.$emit('modal-show', 'modal-signup')
    },
    onCheckoutLoad () {
      this.personalDetails = this.$store.state.checkout.personalDetails
    }
  },
  updated () {
    // Perform focusing on a field, name of which is passed through 'focusedField' prop
    if (this.focusedField && !this.isValidationError) {
      if (this.focusedField === 'password') {
        this.isValidationError = true
        this.password = ''
        this.rPassword = ''
        this.$refs['password'].setFocus('password')
      }
    }
  },
  beforeMount () {
    this.$bus.$on('checkout-after-load', this.onCheckoutLoad)
    this.$bus.$on('user-after-loggedin', this.onLoggedIn)
  },
  beforeDestroy () {
    this.$bus.$off('checkout-after-load', this.onCheckoutLoad)
    this.$bus.$off('user-after-loggedin', this.onLoggedIn)
  }
}
Example #8
Source File: Shipping.ts    From vue-storefront-1 with MIT License 4 votes vote down vote up
Shipping = {
  name: 'Shipping',
  props: {
    isActive: {
      type: Boolean,
      required: true
    }
  },
  beforeDestroy () {
    this.$bus.$off('checkout-after-load', this.onCheckoutLoad)
    this.$bus.$off('checkout-after-personalDetails', this.onAfterPersonalDetails)
    this.$bus.$off('checkout-after-shippingset', this.onAfterShippingSet)
  },
  beforeMount () {
    this.$bus.$on('checkout-after-load', this.onCheckoutLoad)
    this.$bus.$on('checkout-after-personalDetails', this.onAfterPersonalDetails)
    this.$bus.$on('checkout-after-shippingset', this.onAfterShippingSet)
  },
  data () {
    return {
      isFilled: false,
      countries: Countries,
      shipping: this.$store.state.checkout.shippingDetails,
      shipToMyAddress: false,
      myAddressDetails: {
        firstname: '',
        lastname: '',
        country: '',
        region: '',
        city: '',
        street: ['', ''],
        postcode: '',
        telephone: ''
      }
    }
  },
  computed: {
    ...mapState({
      currentUser: (state: RootState) => state.user.current
    }),
    ...mapGetters({
      shippingMethods: 'checkout/getShippingMethods'
    }),
    checkoutShippingDetails () {
      return this.$store.state.checkout.shippingDetails
    },
    paymentMethod () {
      return this.$store.getters['checkout/getPaymentMethods']
    }
  },
  watch: {
    shippingMethods: {
      handler () {
        this.checkDefaultShippingMethod()
      }
    },
    shipToMyAddress: {
      handler () {
        this.useMyAddress()
      }
    },
    '$route.hash': 'useMyAddress'
  },
  mounted () {
    this.checkDefaultShippingAddress()
    this.checkDefaultShippingMethod()
    this.changeShippingMethod()
  },
  methods: {
    checkDefaultShippingAddress () {
      this.shipToMyAddress = this.hasShippingDetails()
    },
    checkDefaultShippingMethod () {
      if (!this.shipping.shippingMethod || this.notInMethods(this.shipping.shippingMethod)) {
        let shipping = this.shippingMethods.find(item => item.default)
        if (!shipping && this.shippingMethods && this.shippingMethods.length > 0) {
          shipping = this.shippingMethods[0]
        }
        this.shipping.shippingMethod = shipping.method_code
        this.shipping.shippingCarrier = shipping.carrier_code
      }
    },
    onAfterShippingSet (receivedData) {
      this.shipping = receivedData
      this.isFilled = true
    },
    onAfterPersonalDetails (receivedData) {
      if (!this.isFilled) {
        this.$store.dispatch('checkout/updatePropValue', ['firstName', receivedData.firstName])
        this.$store.dispatch('checkout/updatePropValue', ['lastName', receivedData.lastName])
      }
      this.useMyAddress()
    },
    sendDataToCheckout () {
      this.$bus.$emit('checkout-after-shippingDetails', this.shipping, this.$v)
      this.isFilled = true
    },
    edit () {
      if (this.isFilled) {
        this.$bus.$emit('checkout-before-edit', 'shipping')
      }
    },
    hasShippingDetails () {
      if (this.currentUser) {
        if (this.currentUser.hasOwnProperty('default_shipping')) {
          let id = this.currentUser.default_shipping
          let addresses = this.currentUser.addresses
          for (let i = 0; i < addresses.length; i++) {
            if (toString(addresses[i].id) === toString(id)) {
              this.myAddressDetails = addresses[i]
              return true
            }
          }
        }
      }
      return false
    },
    useMyAddress () {
      if (this.shipToMyAddress) {
        this.$set(this, 'shipping', {
          firstName: this.myAddressDetails.firstname,
          lastName: this.myAddressDetails.lastname,
          country: this.myAddressDetails.country_id,
          state: this.myAddressDetails.region.region ? this.myAddressDetails.region.region : '',
          city: this.myAddressDetails.city,
          streetAddress: this.myAddressDetails.street[0],
          apartmentNumber: this.myAddressDetails.street[1],
          zipCode: this.myAddressDetails.postcode,
          phoneNumber: this.myAddressDetails.telephone,
          shippingMethod: this.checkoutShippingDetails.shippingMethod,
          shippingCarrier: this.checkoutShippingDetails.shippingCarrier
        })
      } else {
        this.$set(this, 'shipping', this.checkoutShippingDetails)
      }
      this.changeCountry()
    },
    getShippingMethod () {
      for (let i = 0; i < this.shippingMethods.length; i++) {
        if (this.shippingMethods[i].method_code === this.shipping.shippingMethod) {
          return {
            method_title: this.shippingMethods[i].method_title,
            amount: this.shippingMethods[i].amount
          }
        }
      }
      return {
        method_title: '',
        amount: ''
      }
    },
    getCountryName () {
      for (let i = 0; i < this.countries.length; i++) {
        if (this.countries[i].code === this.shipping.country) {
          return this.countries[i].name
        }
      }
      return ''
    },
    changeCountry () {
      this.$bus.$emit('checkout-before-shippingMethods', this.shipping.country)
    },
    getCurrentShippingMethod () {
      let shippingCode = this.shipping.shippingMethod
      let currentMethod = this.shippingMethods ? this.shippingMethods.find(item => item.method_code === shippingCode) : {}
      return currentMethod
    },
    changeShippingMethod () {
      let currentShippingMethod = this.getCurrentShippingMethod()
      if (currentShippingMethod) {
        this.shipping = Object.assign(this.shipping, { shippingCarrier: currentShippingMethod.carrier_code })
        this.$bus.$emit('checkout-after-shippingMethodChanged', {
          country: this.shipping.country,
          method_code: currentShippingMethod.method_code,
          carrier_code: currentShippingMethod.carrier_code,
          payment_method: this.paymentMethod[0].code
        })
      }
    },
    notInMethods (method) {
      let availableMethods = this.shippingMethods
      if (availableMethods.find(item => item.method_code === method)) {
        return false
      }
      return true
    },
    onCheckoutLoad () {
      this.shipping = this.$store.state.checkout.shippingDetails
    }
  }
}