forked from gristlabs/grist-widget
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
558 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const exampleData = { | ||
Number: 14999, | ||
Issued: Date.parse('2020-10-12') / 1000, | ||
Due: Date.parse('2020-11-12') / 1000, | ||
|
||
Invoicer: { | ||
Name: 'Thunderous Applause', | ||
Street1: '812 Automated Rd', | ||
Street2: null, | ||
City: 'New York', | ||
State: 'NY', | ||
Zip: '10003', | ||
Email: '[email protected]', | ||
Phone: '+1-800-111-1111', | ||
Website: 'applause.com', | ||
}, | ||
|
||
Client: { | ||
Name: 'Monkeys Juggling', | ||
Street1: '100 Banana St', | ||
City: 'Bananaberg', | ||
State: 'NJ', | ||
Zip: '07048', | ||
}, | ||
|
||
Items: [ | ||
{ | ||
Description: 'Wolf Whistle', | ||
Price: 35, | ||
Quantity: 3, | ||
Total: 105, | ||
}, | ||
{ | ||
Description: 'Bravo', | ||
Price: 30, | ||
Quantity: 17, | ||
Total: 510, | ||
}, | ||
], | ||
|
||
Subtotal: 615, | ||
Deduction: null, | ||
Taxes: null, | ||
Total: 615, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Grist Invoice</title> | ||
|
||
<!-- A template for showing an invoice in a Custom Widget in Grist. --> | ||
<!-- Uses Vue.js, moment, and the Grist Plugin API --> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script> | ||
<script src="https://docs.getgrist.com/grist-plugin-api.js"></script> | ||
|
||
<script src="invoice.js?ver=11"></script> | ||
<script src="exampleData.js"></script> | ||
|
||
<link rel="stylesheet" href="invoice.css?ver=17"> | ||
</head> | ||
<body> | ||
<div id="app"> | ||
<div class="status" v-if="status"> | ||
<template v-if="status === 'waiting'"> | ||
<p>Waiting for data...</p> | ||
<ul> | ||
<li v-bind:class="[tableConnected ? 'done' : '']">I need <b>read table</b> access.</li> | ||
<li v-bind:class="[haveRows ? 'done' : '']">I need at least one row of data.</li> | ||
<li v-bind:class="[rowConnected ? 'done' : '']">I need <b>Select By</b> set.</li> | ||
</ul> | ||
<p>Examples:</p> | ||
<ul> | ||
<li><a class="button" href="index.html?demo=1">A filled out invoice</a></li> | ||
<li><a class="button" href="index.html?labels=1">A labelled invoice</a></li> | ||
</ul> | ||
</template> | ||
<template v-else> | ||
{{ status }} | ||
</template> | ||
</div> | ||
<template v-if="invoice"> | ||
<div class="top"> | ||
<div class="block"> | ||
<div class="header"> | ||
<div class="meta title">Invoice</div> | ||
</div> | ||
<div class="info"><span class="meta">Invoice Number</span> #{{ invoice.Number }}</div> | ||
<div class="info" v-if="invoice.Issued"><div class="meta date-tag">Issued</div> {{ invoice.Issued | asDate }}</div> | ||
<div class="info" v-if="invoice.Due"><div class="meta date-tag">Due</div> {{ invoice.Due | asDate }}</div> | ||
</div> | ||
|
||
<div class="supplier"> | ||
<div v-for="business in (invoice.Invoicer ? [invoice.Invoicer] : [])"> | ||
<template v-if="typeof(business) === 'string'"> | ||
<div class="address newlined">{{ business }}</div> | ||
</template> | ||
<template v-else> | ||
<div class="address"> | ||
<span class="name">{{ business.Name }}</span><br /> | ||
{{ business.Street1 }}<br /> | ||
<template v-if="business.Street2"> | ||
{{ business.Street2 }}<br /> | ||
</template> | ||
{{ business.City }} {{ business.State }} {{ business.Zip }}<br /> | ||
<template v-if="business.Country"> | ||
{{ business.Country }}<br /> | ||
</template> | ||
</div> | ||
<template v-if="business.Email"> | ||
<div class="email">{{ business.Email }}</div> | ||
</template> | ||
<template v-if="business.Phone"> | ||
<div class="phone">{{ business.Phone }}</div> | ||
</template> | ||
<template v-if="business.Website"> | ||
<div class="website"><a v-bind:href="business.Url">{{ business.Website }}</a></div> | ||
</template> | ||
</template> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="client" v-for="business in (invoice.Client ? [invoice.Client] : [])"> | ||
<div class="title">Client</div> | ||
<div class="details"> | ||
<template v-if="typeof(business) === 'string'"> | ||
<div class="newlined">{{ business }}</div> | ||
</template> | ||
<template v-else> | ||
<div>{{ business.Name }}</div> | ||
<template v-if="business.Street1"> | ||
{{ business.Street1 }}, | ||
</template> | ||
<template v-if="business.Street2"> | ||
{{ business.Street2 }}, | ||
</template> | ||
{{ business.City }} {{ business.State }} {{ business.Zip }} | ||
<template v-if="business.Country"> | ||
<br />{{ business.Country }} | ||
</template> | ||
</template> | ||
</div> | ||
</div> | ||
|
||
<table class="items"> | ||
<template v-if="!Array.isArray(invoice.Items)"> | ||
<tr> | ||
<th>Description</th> | ||
<th class="money">Total</th> | ||
</tr> | ||
<tr> | ||
<td>{{ invoice.Items }}</td> | ||
<td class="money">{{ invoice.Total | currency }}</td> | ||
</tr> | ||
</template> | ||
<template v-else> | ||
<tr> | ||
<th>Description</th> | ||
<th class="money">Unit Price</th> | ||
<th class="number">Quantity</th> | ||
<th class="money">Total</th> | ||
</tr> | ||
<tr v-for="item in invoice.Items"> | ||
<td>{{ item.Description }}</td> | ||
<td class="money">{{ item.Price | currency }}</td> | ||
<td class="number">{{ item.Quantity }}</td> | ||
<td class="money">{{ item.Total | currency }}</td> | ||
</tr> | ||
</template> | ||
</table> | ||
|
||
<div class="summary"> | ||
<div class="part"> | ||
<div class="title">Subtotal</div> | ||
<div class="details">{{ invoice.Subtotal | currency }}</div> | ||
</div> | ||
<div class="part"> | ||
<div class="title">Deduction</div> | ||
<div class="details">{{ invoice.Deduction | currency }}</div> | ||
</div> | ||
<div class="part"> | ||
<div class="title">Taxes</div> | ||
<div class="details">{{ invoice.Taxes | currency }}</div> | ||
</div> | ||
<div class="total"> | ||
<div class="title">Total</div> | ||
<div class="details">{{ invoice.Total | currency }}</div> | ||
</div> | ||
</div> | ||
|
||
<template v-if="invoice.Note"> | ||
<p class="note">{{ invoice.Note }}</p> | ||
</template> | ||
|
||
<template v-for="help in (invoice.Help ? [invoice.Help] : [])"> | ||
<div class="help"> | ||
<div class="help-close"> | ||
Add <span class="column-name">Due</span> or <span class="column-name">Issued</span> date to hide this help. | ||
</div> | ||
<div class="title">Column information</div> | ||
<div class="details"> | ||
<table> | ||
<tr v-for="group in ['recognized', 'expected', 'ignored']"> | ||
<td class="key">{{ group }}</td> | ||
<td> | ||
<template v-if="group in help"> | ||
<div v-bind:class="['column-name', 'column-' + group]" v-for="col in help[group]">{{col}}</div> | ||
</template> | ||
<template v-else> | ||
— | ||
</template> | ||
</td> | ||
</tr> | ||
</table> | ||
<template v-if="invoice.SuggestReferencesColumn"> | ||
<div>For structured address and item information, add a <span class="column-name">References</span> column with this formula:</div> | ||
<div> | ||
<pre>RECORD(rec, expand_refs=1)</pre> | ||
</div> | ||
</template> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<div class="footer"> | ||
<div class="thanks"> | ||
Thank you! | ||
</div> | ||
</div> | ||
|
||
<div class="print"> | ||
<a href="javascript:window.print()">Print</a> | ||
</div> | ||
</template> | ||
</div> | ||
</body> | ||
</html> |
Oops, something went wrong.