Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Format and lint
  • Loading branch information
presleyp committed Aug 24, 2022
commit 17d8d1b5866cf26b92c6cf1dfba77d5a32e2ef14
6 changes: 5 additions & 1 deletion site/src/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ export const AppRouter: FC = () => {
<Navigate to="/workspaces" />
) : (
<AuthAndFrame>
<RequirePermission isFeatureVisible={featureVisibility[FeatureNames.AuditLog] && !!permissions?.viewAuditLog}>
<RequirePermission
isFeatureVisible={
featureVisibility[FeatureNames.AuditLog] && !!permissions?.viewAuditLog
}
>
<AuditPage />
</RequirePermission>
</AuthAndFrame>
Expand Down
2 changes: 1 addition & 1 deletion site/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export type Message = { message: string }
// Keep up to date with coder/codersdk/features.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that can be autogenerated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is there's some reason why we can't get enums in our generated types.

export enum FeatureNames {
AuditLog = "audit_log",
UserLimit = "user_limit"
UserLimit = "user_limit",
}
8 changes: 1 addition & 7 deletions site/src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,5 @@ export const Navbar: React.FC = () => {
const canViewAuditLog = featureVisibility[FeatureNames.AuditLog] && !!permissions?.viewAuditLog
const onSignOut = () => authSend("SIGN_OUT")

return (
<NavbarView
user={me}
onSignOut={onSignOut}
canViewAuditLog={canViewAuditLog}
/>
)
return <NavbarView user={me} onSignOut={onSignOut} canViewAuditLog={canViewAuditLog} />
}
2 changes: 1 addition & 1 deletion site/src/testHelpers/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,6 @@ export const MockEntitlementsWithWarnings: TypesGen.Entitlements = {
audit_log: {
enabled: true,
entitlement: "entitled",
}
},
},
}
24 changes: 17 additions & 7 deletions site/src/xServices/entitlements/entitlementsSelectors.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
import { getFeatureVisibility } from "./entitlementsSelectors"

describe('getFeatureVisibility', () => {
describe("getFeatureVisibility", () => {
it("returns empty object if there is no license", () => {
const result = getFeatureVisibility(false, { audit_log: { entitlement: "entitled", enabled: true } })
const result = getFeatureVisibility(false, {
audit_log: { entitlement: "entitled", enabled: true },
})
expect(result).toEqual(expect.objectContaining({}))
})
it('returns false for a feature that is not enabled', () => {
const result = getFeatureVisibility(true, { audit_log: { entitlement: "entitled", enabled: false } })
it("returns false for a feature that is not enabled", () => {
const result = getFeatureVisibility(true, {
audit_log: { entitlement: "entitled", enabled: false },
})
expect(result).toEqual(expect.objectContaining({ audit_log: false }))
})
it("returns false for a feature that is not entitled", () => {
const result = getFeatureVisibility(true, { audit_log: { entitlement: "not_entitled", enabled: true } })
const result = getFeatureVisibility(true, {
audit_log: { entitlement: "not_entitled", enabled: true },
})
expect(result).toEqual(expect.objectContaining({ audit_log: false }))
})
it("returns true for a feature that is in grace period", () => {
const result = getFeatureVisibility(true, { audit_log: { entitlement: "grace_period", enabled: true } })
const result = getFeatureVisibility(true, {
audit_log: { entitlement: "grace_period", enabled: true },
})
expect(result).toEqual(expect.objectContaining({ audit_log: true }))
})
it("returns true for a feature that is in entitled", () => {
const result = getFeatureVisibility(true, { audit_log: { entitlement: "entitled", enabled: true } })
const result = getFeatureVisibility(true, {
audit_log: { entitlement: "entitled", enabled: true },
})
expect(result).toEqual(expect.objectContaining({ audit_log: true }))
})
})
19 changes: 12 additions & 7 deletions site/src/xServices/entitlements/entitlementsSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@ type EntitlementState = State<EntitlementsContext, EntitlementsEvent>
* @param features record from feature name to feature object
* @returns record from feature name whether to show the feature
*/
export const getFeatureVisibility = (hasLicense: boolean, features: Record<string, Feature>): Record<string, boolean> => {
export const getFeatureVisibility = (
hasLicense: boolean,
features: Record<string, Feature>,
): Record<string, boolean> => {
if (hasLicense) {
const permissionPairs = Object.keys(features).map((feature) => {
const { entitlement, limit, actual, enabled } = features[feature]
const entitled = ["entitled", "grace_period"].includes(entitlement)
const limitCompliant = (limit && actual) ? limit >= actual : true
return [feature, entitled && limitCompliant && enabled]
const { entitlement, limit, actual, enabled } = features[feature]
const entitled = ["entitled", "grace_period"].includes(entitlement)
const limitCompliant = limit && actual ? limit >= actual : true
return [feature, entitled && limitCompliant && enabled]
})
console.log(permissionPairs, Object.fromEntries(permissionPairs))
return Object.fromEntries(permissionPairs)
} else {
return {}
}
}

export const selectFeatureVisibility = (state: EntitlementState): Record<string, boolean> => {
return getFeatureVisibility(state.context.entitlements.has_license, state.context.entitlements.features)
return getFeatureVisibility(
state.context.entitlements.has_license,
state.context.entitlements.features,
)
}
2 changes: 1 addition & 1 deletion site/src/xServices/entitlements/entitlementsXService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const entitlementsMachine = createMachine(
on: {
GET_ENTITLEMENTS: "gettingEntitlements",
SHOW_MOCK_BANNER: { actions: "assignMockEntitlements" },
HIDE_MOCK_BANNER: "gettingEntitlements"
HIDE_MOCK_BANNER: "gettingEntitlements",
},
},
gettingEntitlements: {
Expand Down