[NEW] Subscription enabled marketplace (#14948)
* Show the subscription apps different from regular purchase prices * Update app download calls return a Buffer directly * Add X-Apps-Engine-Version header to marketplace requests * Add getActiveUserCount method to apps-engine user bridge * Add distinction for purchase type on apps list * Fix the issues with displaying subscriptions * Remove external federated users from active user count * Fix usage of federation module * Change app installation to validate license * Change the bridges to correctly query the workspace public key * Change marketplaceUrl to marketplace-beta * Update Apps and Marketplace styles (temp) * Update price column on Marketplace * Update status column on Marketplace * Fix Marketplace app list update * Remove log from client orchestrator * Refactor server orchestrator * Change rest api for license validation * Add popover to Marketplace app list * Add card (subscription) icon * Update active user count method * Update appManage template (partial) * Update appManage template * Add missing i18n strings * Add cron routine to update apps info * Add options parameter to new methods on model Users * Revert testing settings * Bump Apps-Engine versionpull/15015/head^2
parent
d022df2ec5
commit
3fb0cca52f
@ -0,0 +1,147 @@ |
||||
#rocket-chat .content .rc-apps-details { |
||||
&__content { |
||||
justify-content: flex-start; |
||||
} |
||||
|
||||
&__app-name { |
||||
flex: 0 0 1.75rem; |
||||
|
||||
margin: 0; |
||||
|
||||
letter-spacing: 0; |
||||
text-transform: none; |
||||
|
||||
color: rgb(84, 88, 94); |
||||
|
||||
font-family: inherit; |
||||
font-size: 1.375rem; |
||||
font-weight: normal; |
||||
line-height: 1.75rem; |
||||
} |
||||
|
||||
&__app-info { |
||||
display: flex; |
||||
flex: 0 0 1.25rem; |
||||
flex-wrap: nowrap; |
||||
|
||||
> span::after { |
||||
display: inline-block; |
||||
|
||||
width: 1px; |
||||
height: 12px; |
||||
margin: 0 8px; |
||||
|
||||
content: ''; |
||||
|
||||
background: rgb(203, 206, 209); |
||||
} |
||||
|
||||
> span:last-child::after { |
||||
display: none; |
||||
|
||||
content: none; |
||||
} |
||||
} |
||||
|
||||
&__app-author { |
||||
letter-spacing: -0.2px; |
||||
|
||||
color: rgb(158, 162, 168); |
||||
|
||||
font-family: inherit; |
||||
font-size: 14px; |
||||
font-weight: 500; |
||||
line-height: 20px; |
||||
} |
||||
|
||||
&__app-version { |
||||
letter-spacing: -0.2px; |
||||
|
||||
color: rgb(158, 162, 168); |
||||
|
||||
font-family: inherit; |
||||
font-size: 14px; |
||||
font-weight: normal; |
||||
line-height: 20px; |
||||
} |
||||
|
||||
&__app-status { |
||||
display: flex; |
||||
flex: 1; |
||||
|
||||
margin-top: 8px; |
||||
align-items: center; |
||||
} |
||||
|
||||
&__app-install-status { |
||||
display: flex; |
||||
|
||||
height: 40px; |
||||
|
||||
letter-spacing: 0; |
||||
|
||||
color: rgb(158, 162, 168); |
||||
|
||||
font-family: inherit; |
||||
font-size: 14px; |
||||
font-weight: 500; |
||||
align-items: center; |
||||
flex-wrap: nowrap; |
||||
|
||||
& > .rc-icon { |
||||
color: var(--rc-color-button-primary); |
||||
} |
||||
} |
||||
|
||||
&__app-price { |
||||
letter-spacing: -0.2px; |
||||
|
||||
color: rgb(157, 161, 168); |
||||
|
||||
font-family: inherit; |
||||
font-size: 14px; |
||||
font-weight: normal; |
||||
line-height: 20px; |
||||
|
||||
&::before { |
||||
display: inline-block; |
||||
|
||||
width: 1px; |
||||
height: 12px; |
||||
margin: 0 16px; |
||||
|
||||
content: ''; |
||||
|
||||
background: rgb(203, 206, 209); |
||||
} |
||||
} |
||||
|
||||
&__app-button-wrapper { |
||||
flex: 1; |
||||
} |
||||
|
||||
& .rc-button.loading { |
||||
padding: 0 1.5rem; |
||||
|
||||
opacity: 0.6; |
||||
|
||||
&::before { |
||||
display: none; |
||||
} |
||||
|
||||
& > .rc-icon { |
||||
animation: spin 1s linear infinite; |
||||
} |
||||
} |
||||
|
||||
&__app-menu-trigger { |
||||
padding: 0; |
||||
|
||||
&::before { |
||||
display: inline-block; |
||||
flex: 1; |
||||
|
||||
content: ''; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@ |
||||
.rc-apps-marketplace { |
||||
&__app-status, |
||||
&__app-button, |
||||
&__app-menu-trigger { |
||||
display: flex; |
||||
flex: 1; |
||||
|
||||
padding: 0; |
||||
|
||||
font-size: 0.875rem; |
||||
line-height: 1.25rem; |
||||
align-items: center; |
||||
appearance: none; |
||||
} |
||||
|
||||
&__app-menu-trigger, |
||||
&__app-button { |
||||
position: relative; |
||||
|
||||
&:active { |
||||
transform: translateY(2px); |
||||
|
||||
opacity: 0.9; |
||||
} |
||||
|
||||
&:active::before { |
||||
top: -2px; |
||||
} |
||||
|
||||
&::before { |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
bottom: 0; |
||||
left: 0; |
||||
|
||||
content: ""; |
||||
cursor: pointer; |
||||
} |
||||
} |
||||
|
||||
&__app-button { |
||||
color: var(--rc-color-button-primary); |
||||
|
||||
&.loading { |
||||
opacity: 0.6; |
||||
|
||||
& > .rc-icon { |
||||
animation: spin 1s linear infinite; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&__app-menu-trigger { |
||||
visibility: hidden; |
||||
flex: 0 0 auto; |
||||
} |
||||
|
||||
.rc-table-content .rc-table { |
||||
.rc-table-tr:hover .rc-apps-marketplace__app-menu-trigger { |
||||
visibility: visible; |
||||
} |
||||
|
||||
.rc-table-td--small:last-child { |
||||
width: 150px; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@ |
||||
import { Meteor } from 'meteor/meteor'; |
||||
import { HTTP } from 'meteor/http'; |
||||
import { SyncedCron } from 'meteor/littledata:synced-cron'; |
||||
|
||||
import { Apps } from './orchestrator'; |
||||
import { getWorkspaceAccessToken } from '../../cloud/server'; |
||||
import { Settings } from '../../models/server'; |
||||
|
||||
export const appsUpdateMarketplaceInfo = Meteor.bindEnvironment(() => { |
||||
const token = getWorkspaceAccessToken(); |
||||
const baseUrl = Apps.getMarketplaceUrl(); |
||||
const [workspaceIdSetting] = Settings.findById('Cloud_Workspace_Id').fetch(); |
||||
|
||||
const fullUrl = `${ baseUrl }/v1/workspaces/${ workspaceIdSetting.value }/apps`; |
||||
const options = { |
||||
headers: { |
||||
Authorization: `Bearer ${ token }`, |
||||
}, |
||||
}; |
||||
|
||||
let data = []; |
||||
|
||||
try { |
||||
const result = HTTP.get(fullUrl, options); |
||||
|
||||
if (Array.isArray(result.data)) { |
||||
data = result.data; |
||||
} |
||||
} catch (err) { |
||||
Apps.debugLog(err); |
||||
} |
||||
|
||||
Promise.await(Apps.updateAppsMarketplaceInfo(data)); |
||||
}); |
||||
|
||||
SyncedCron.add({ |
||||
name: 'Apps-Engine:check', |
||||
schedule: (parser) => parser.text('at 4:00 pm'), |
||||
job() { |
||||
appsUpdateMarketplaceInfo(); |
||||
}, |
||||
}); |
||||
|
||||
SyncedCron.start(); |
@ -1 +1,3 @@ |
||||
import './cron'; |
||||
|
||||
export { Apps } from './orchestrator'; |
||||
|
After Width: | Height: | Size: 828 B |
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 205 KiB |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue