Skip to content

Commit

Permalink
Merge pull request #11 from fleetbase/dev-v0.0.12
Browse files Browse the repository at this point in the history
v0.0.12
  • Loading branch information
roncodes authored Aug 6, 2024
2 parents 118af76 + 50eb883 commit 856b720
Show file tree
Hide file tree
Showing 20 changed files with 407 additions and 31 deletions.
5 changes: 5 additions & 0 deletions addon/components/extension-card.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
<div class="flex flex-col">
<div class="font-semibold text-sm block {{@nameTextClass}}">{{@extension.name}}</div>
<div class="text-xs {{@descriptionTextClass}}">{{n-a @extension.description}}</div>
{{#if @extension.payment_required}}
<Badge @status="success" @hideStatusDot={{true}}>{{format-currency @extension.price @extension.currency}}</Badge>
{{else}}
<Badge @status="success" @hideStatusDot={{true}}>Free</Badge>
{{/if}}
</div>
{{yield @extension}}
</div>
Expand Down
47 changes: 46 additions & 1 deletion addon/components/extension-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,21 @@ export default class ExtensionCardComponent extends Component {

@action onClick(options = {}) {
const installChannel = `install.${this.currentUser.companyId}.${this.extension.id}`;
const isAuthor = this.extension.is_author === true;
const isSelfManaged = this.extension.self_managed === true;
const isAlreadyPurchased = this.extension.is_purchased === true;
const isAlreadyInstalled = this.extension.is_installed === true;
const isPaymentRequired = this.extension.payment_required === true && isAlreadyPurchased === false;
const isPaymentRequired = !isAuthor && this.extension.payment_required === true && isAlreadyPurchased === false;
const goBack = async (modal) => {
await modal.done();
later(
this,
() => {
this.onClick();
},
100
);
};

if (typeof this.args.onClick === 'function') {
this.args.onClick(this.extension);
Expand All @@ -63,6 +75,13 @@ export default class ExtensionCardComponent extends Component {
stepDescription: 'Awaiting install to begin...',
progress: 0,
extension: this.extension,
viewSelfManagesInstallInstructions: () => {
this.selfManagedInstallInstructions({
extension: this.extension,
confirm: goBack,
decline: goBack,
});
},
confirm: async (modal) => {
modal.startLoading();

Expand All @@ -71,6 +90,22 @@ export default class ExtensionCardComponent extends Component {
return this.startCheckoutSession();
}

// If self managed just prompt instructions
if (isSelfManaged) {
await modal.done();
return later(
this,
() => {
return this.selfManagedInstallInstructions({
extension: this.extension,
confirm: goBack,
decline: goBack,
});
},
100
);
}

// Listen for install progress
this.socket.listen(installChannel, ({ process, step, progress }) => {
let stepDescription;
Expand Down Expand Up @@ -121,6 +156,16 @@ export default class ExtensionCardComponent extends Component {
});
}

async selfManagedInstallInstructions(options = {}) {
await this.modalsManager.done();
this.modalsManager.show('modals/self-managed-install-instructions', {
title: 'Install a Self Managed Extension',
hideDeclineButton: true,
acceptButtonText: 'Done',
...options,
});
}

async startCheckoutSession() {
const checkout = await this.stripe.initEmbeddedCheckout({
fetchClientSecret: this.fetchClientSecret.bind(this),
Expand Down
22 changes: 20 additions & 2 deletions addon/components/extension-form.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@

<InputGroup
@name={{t "registry-bridge.developers.extensions.extension-form.extension-tags"}}
@wrapperClass="mb-0i"
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-tags-help-text"}}
>
<TagInput
Expand All @@ -85,6 +84,19 @@
{{tag}}
</TagInput>
</InputGroup>

<InputGroup @wrapperClass="mb-0i">
<Toggle
@isToggled={{@extension.self_managed}}
@onToggle={{fn (mut @extension.self_managed)}}
@helpText={{t "registry-bridge.developers.extensions.extension-form.self-managed-help-text"}}
>
<span class="dark:text-gray-100 text-sm mx-2">{{t "registry-bridge.developers.extensions.extension-form.self-managed"}}</span>
</Toggle>
<p class="mt-2 text-xs bg-blue-800 border border-blue-600 px-2 py-2 rounded-md text-blue-100">
{{t "registry-bridge.developers.extensions.extension-form.self-managed-help-text"}}
</p>
</InputGroup>
</ContentPanel>
<ContentPanel @title={{t "registry-bridge.developers.extensions.extension-form.extension-bundle"}} @open={{true}} @pad={{false}} @panelBodyClass="bg-white dark:bg-gray-800">
<div class="px-4 pb-4 pt-3 flex flex-col flex-grow-0">
Expand All @@ -101,7 +113,13 @@
{{/if}}
</div>
</ContentPanel>
<ContentPanel @title={{t "registry-bridge.developers.extensions.extension-form.extension-listing-details"}} @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
<ContentPanel
@title={{t "registry-bridge.developers.extensions.extension-form.extension-listing-details"}}
@open={{true}}
@pad={{true}}
@panelBodyClass="bg-white dark:bg-gray-800"
@actionButtons={{this.listingDetailsPanelActions}}
>
<InputGroup
@name={{t "registry-bridge.developers.extensions.extension-form.extension-promotional-text"}}
@helpText={{t "registry-bridge.developers.extensions.extension-form.extension-promotional-text-help-text"}}
Expand Down
57 changes: 57 additions & 0 deletions addon/components/extension-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';
import { later } from '@ember/runloop';
import formatCurrency from '@fleetbase/ember-ui/utils/format-currency';

export default class ExtensionFormComponent extends Component {
@service store;
Expand All @@ -13,6 +15,14 @@ export default class ExtensionFormComponent extends Component {
@tracked subscriptionModelOptions = ['flat_rate', 'tiered', 'usage'];
@tracked billingPeriodOptions = ['daily', 'weekly', 'monthly', 'quarterly', 'yearly'];
@tracked uploadQueue = [];
listingDetailsPanelActions = [
{
type: 'link',
size: 'xs',
text: 'Preview Listing',
onClick: this.previewListing,
},
];
acceptedImageTypes = ['image/jpeg', 'image/png', 'image/gif'];
acceptedBundleTypes = [
'application/zip',
Expand Down Expand Up @@ -120,4 +130,51 @@ export default class ExtensionFormComponent extends Component {
@action removeFile(file) {
return file.destroyRecord();
}

@action previewListing(options = {}) {
const extension = this.args.extension;
const isAlreadyPurchased = extension.is_purchased === true;
const isAlreadyInstalled = extension.is_installed === true;
const isPaymentRequired = extension.payment_required === true && isAlreadyPurchased === false;
const goBack = async (modal) => {
await modal.done();
later(
this,
() => {
this.previewListing();
},
100
);
};

this.modalsManager.show('modals/extension-details', {
titleComponent: 'extension-modal-title',
modalClass: 'flb--extension-modal modal-lg',
modalHeaderClass: 'flb--extension-modal-header',
acceptButtonText: isPaymentRequired ? `Purchase for ${formatCurrency(extension.price, extension.currency)}` : isAlreadyInstalled ? 'Installed' : 'Install',
acceptButtonIcon: isPaymentRequired ? 'credit-card' : isAlreadyInstalled ? 'check' : 'download',
acceptButtonDisabled: true,
acceptButtonScheme: isPaymentRequired ? 'success' : 'primary',
declineButtonText: 'Done',
viewSelfManagesInstallInstructions: () => {
this.selfManagedInstallInstructions({
extension,
confirm: goBack,
decline: goBack,
});
},
extension,
...options,
});
}

async selfManagedInstallInstructions(options = {}) {
await this.modalsManager.done();
this.modalsManager.show('modals/self-managed-install-instructions', {
title: 'Install a Self Managed Extension',
hideDeclineButton: true,
acceptButtonText: 'Done',
...options,
});
}
}
49 changes: 34 additions & 15 deletions addon/components/modals/extension-details.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="modal-body-container space-y-3">
<div class="flex flex-row items-center space-x-2">
<div class="flb--extension-tag shadow-sm border dark:bg-gray-800 dark:border-gray-800 dark:text-gray-200">
Extension
{{t "registry-bridge.component.extension-details-modal.extension"}}
</div>
<div class="flb--extension-tag shadow-sm border dark:bg-gray-800 dark:border-gray-800 dark:text-gray-200">
{{this.extension.category_name}}
Expand All @@ -28,40 +28,59 @@
{{/if}}
{{/if}}
<div>
<h3 class="dark:text-white font-semibold mb-1">Overview</h3>
<h3 class="dark:text-white font-semibold mb-1">{{t "registry-bridge.component.extension-details-modal.overview"}}</h3>
<div class="space-y-1">
<p class="dark:text-gray-200 text-sm">{{this.extension.description}}</p>
<p class="dark:text-gray-200 text-sm">{{html-safe this.extension.promotional_text}}</p>
</div>
</div>
<div>
<h3 class="dark:text-white font-semibold mb-1">Details</h3>
<h3 class="dark:text-white font-semibold mb-1">{{t "registry-bridge.component.extension-details-modal.details"}}</h3>
<div class="space-y-2">
<div class="grid grid-cols-4 gap-2">
<div class="space-y-2">
<div>
<div class="text-sm font-semibold dark:text-gray-100">Version</div>
<div class="text-sm dark:text-gray-200">{{this.extension.current_bundle_version}}</div>
<div class="text-sm font-semibold dark:text-gray-100">{{t "registry-bridge.component.extension-details-modal.version"}}</div>
<div class="text-sm dark:text-gray-200">{{n-a this.extension.current_bundle_version}}</div>
</div>
<div>
<div class="text-sm font-semibold dark:text-gray-100">Updated</div>
<div class="text-sm dark:text-gray-200">{{this.extension.updatedAt}}</div>
<div class="text-sm font-semibold dark:text-gray-100">{{t "registry-bridge.component.extension-details-modal.updated"}}</div>
<div class="text-sm dark:text-gray-200">{{n-a this.extension.updatedAt}}</div>
</div>
</div>
<div class="space-y-2">
<div>
<div class="text-sm font-semibold dark:text-gray-100">Author</div>
<div class="text-sm dark:text-gray-200">{{this.extension.publisher_name}}</div>
<div class="text-sm font-semibold dark:text-gray-100">{{t "registry-bridge.component.extension-details-modal.author"}}</div>
<div class="text-sm dark:text-gray-200">{{n-a this.extension.publisher_name}}</div>
</div>
<div>
<div class="text-sm font-semibold dark:text-gray-100">Website</div>
<a
class="text-sm dark:text-gray-200"
href={{this.extension.website_url}}
target={{dasherize (concat this.extension.name "-website")}}
>{{this.extension.website_url}}</a>
<div class="text-sm font-semibold dark:text-gray-100">{{t "registry-bridge.component.extension-details-modal.website"}}</div>
{{#if this.extension.website_url}}
<a
class="text-sm text-blue-400 hover:text-blue-300"
href={{this.extension.website_url}}
target={{dasherize (concat this.extension.name "-website")}}
>{{this.extension.website_url}}</a>
{{else}}
<div class="text-sm dark:text-gray-200">-</div>
{{/if}}
</div>
</div>
<div class="space-y-2">
{{#if this.extension.self_managed}}
<div>
<Badge @status="info" @hideStatusDot={{true}} @helpText={{t "registry-bridge.component.extension-details-modal.self-managed-help-text"}}>{{t
"registry-bridge.component.extension-details-modal.self-managed"
}}</Badge>
{{#if @options.viewSelfManagesInstallInstructions}}
<a href="#" class="text-xs text-blue-400 hover:opacity-50" {{on "click" @options.viewSelfManagesInstallInstructions}}><FaIcon
@icon="circle-info"
class="mr-1"
/>How to install</a>
{{/if}}
</div>
{{/if}}
</div>
</div>
</div>
</div>
Expand Down
40 changes: 40 additions & 0 deletions addon/components/modals/self-managed-install-instructions.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="modal-body-container">
<p class="text-sm mb-4 text-gray-900 dark:text-gray-200">
Begin the installation from the base directory of your Fleetbase instance. For comprehensive instructions, visit the
<a href="https://github.com/fleetbase/fleetbase-cli" target="fleetbase-cli" class="text-blue-400 hover:opacity-50">
<FaIcon @icon="arrow-up-right-from-square" class="text-xs" />
Fleetbase CLI GitHub page</a>.
</p>
<ol class="self-managed-install-instructions">
<li>
<div class="flex">
First,
<LinkTo @route="console.extensions.developers.credentials" class="ml-1 text-blue-400 hover:opacity-50">generate a Fleetbase registry credentials token.</LinkTo>
</div>
</li>
<li>
<div class="flex flex-col">
<div class="mb-2">Install the Fleetbase CLI globally using npm:</div>
<ClickToCopy @value={{concat "npm i -g @fleetbase/cli"}}><code>npm i -g @fleetbase/cli</code></ClickToCopy>
</div>
</li>
<li>
<div class="flex flex-col">
<div class="mb-2">Set your authentication token with the CLI:</div>
<ClickToCopy @value={{concat "flb set-auth {YOUR_TOKEN}"}}><code>flb set-auth {YOUR_TOKEN}</code></ClickToCopy>
</div>
</li>
<li>
<div class="flex flex-col">
<div class="mb-2">Finally, install the extension using one of the following commands:</div>
<div>
<ClickToCopy @value={{concat "flb install fleetbase/" @options.extension.slug}}><code>flb install fleetbase/{{@options.extension.slug}}</code></ClickToCopy>
<div class="my-1 pl-2">or</div>
<ClickToCopy @value={{concat "flb install " @options.extension.public_id}}><code>flb install {{@options.extension.public_id}}</code></ClickToCopy>
</div>
</div>
</li>
</ol>
</div>
</Modal::Default>
2 changes: 2 additions & 0 deletions addon/models/registry-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ export default class RegistryExtensionModel extends Model {
@attr('array') languages;
@attr('object') meta;
@attr('boolean') core_service;
@attr('boolean') self_managed;
@attr('boolean') is_purchased;
@attr('boolean') is_installed;
@attr('boolean') is_author;
@attr('string', { defaultValue: 'pending' }) status;

/** @dates */
Expand Down
31 changes: 31 additions & 0 deletions addon/styles/registry-bridge-engine.css
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,34 @@ body[data-theme='dark'] .extension-card-container > .extension-card-body-contain
margin-left: 2rem;
margin-bottom: 2rem;
}

.self-managed-install-instructions {
list-style: decimal;
color: #000;
padding-left: 30px;
font-size: 0.85rem;
line-height: 1rem;
}

.self-managed-install-instructions > li {
padding-bottom: 1.5rem;
}

body[data-theme='dark'] .self-managed-install-instructions {
list-style: decimal;
color: #fff;
padding-left: 30px;
}

.self-managed-install-instructions code {
display: flex;
font-family: monospace;
padding: 0.25rem 0.75rem;
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
background-color: #1f2937;
border: 1px #374151 solid;
color: #86efac;
border-radius: 0.5rem;
font-size: 0.75rem;
line-height: 1rem;
}
1 change: 1 addition & 0 deletions app/components/modals/self-managed-install-instructions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/registry-bridge-engine/components/modals/self-managed-install-instructions';
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fleetbase/registry-bridge",
"version": "0.0.11",
"version": "0.0.12",
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
"keywords": [
"fleetbase-extension",
Expand Down
2 changes: 1 addition & 1 deletion extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Registry Bridge",
"version": "0.0.11",
"version": "0.0.12",
"description": "Internal Bridge between Fleetbase API and Extensions Registry",
"repository": "https://github.com/fleetbase/registry-bridge",
"license": "AGPL-3.0-or-later",
Expand Down
Loading

0 comments on commit 856b720

Please sign in to comment.