From ef232ca5a93f8c606d4ef269b3989028f53e080c Mon Sep 17 00:00:00 2001 From: Paul Gray Date: Thu, 29 Feb 2024 10:34:45 -0500 Subject: [PATCH] Scaffold LTI Extensions page This commit adds a scaffolded FE for the LTI extensions page in Canvas test plan: Go to Admin -> Extensions and click between Manage/Discover to make sure the routing works and reload pages to make sure the nested urls work. Turn the lti_registrations_discover_page feature flag off to make sure the page the discover page is not accessible, and then turn the lti_registrations_page off to make sure the whole extensions view is not accessible. fixes: INTEROP-8515 flag=lti_registrations_page Change-Id: I7d34b387d03a4bce66325a4791645c6502784b12 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/341783 Tested-by: Service Cloud Jenkins Reviewed-by: Steve Mcgee QA-Review: Steve Mcgee Product-Review: Paul Gray --- app/controllers/application_controller.rb | 1 + .../lti_registrations_controller.rb | 34 +++++++++ app/models/account.rb | 6 ++ app/views/lti_registrations/index.erb | 27 +++++++ .../feature_flags/interop_release_flags.yml | 19 +++++ config/routes.rb | 4 ++ lib/feature_flags/hooks.rb | 7 ++ ui/featureBundles.ts | 1 + .../lti_registrations/discover/Discover.tsx | 27 +++++++ .../lti_registrations/discover/index.tsx | 26 +++++++ ui/features/lti_registrations/index.tsx | 51 +++++++++++++ .../layout/LtiAppsLayout.tsx | 71 +++++++++++++++++++ .../lti_registrations/manage/Manage.tsx | 29 ++++++++ .../lti_registrations/manage/index.tsx | 36 ++++++++++ ui/features/lti_registrations/package.json | 6 ++ ui/shared/global/env/EnvCommon.d.ts | 1 + 16 files changed, 346 insertions(+) create mode 100644 app/controllers/lti_registrations_controller.rb create mode 100644 app/views/lti_registrations/index.erb create mode 100644 ui/features/lti_registrations/discover/Discover.tsx create mode 100644 ui/features/lti_registrations/discover/index.tsx create mode 100644 ui/features/lti_registrations/index.tsx create mode 100644 ui/features/lti_registrations/layout/LtiAppsLayout.tsx create mode 100644 ui/features/lti_registrations/manage/Manage.tsx create mode 100644 ui/features/lti_registrations/manage/index.tsx create mode 100644 ui/features/lti_registrations/package.json diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1a209c8e137..1034c928c07 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -387,6 +387,7 @@ class ApplicationController < ActionController::Base react_discussions_post instui_nav enhanced_developer_keys_tables + lti_registrations_discover_page ].freeze JS_ENV_BRAND_ACCOUNT_FEATURES = [ :embedded_release_notes diff --git a/app/controllers/lti_registrations_controller.rb b/app/controllers/lti_registrations_controller.rb new file mode 100644 index 00000000000..9f50b24d200 --- /dev/null +++ b/app/controllers/lti_registrations_controller.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# +# Copyright (C) 2012 - present Instructure, Inc. +# +# This file is part of Canvas. +# +# Canvas is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, version 3 of the License. +# +# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see . +# + +class LtiRegistrationsController < ApplicationController + def index + require_account_context + + if @context.feature_enabled?(:lti_registrations_page) + set_active_tab "extensions" + add_crumb t("#crumbs.apps", "Extensions") + + render :index + else + render "shared/errors/404_message", status: :not_found, formats: [:html] + end + end +end diff --git a/app/models/account.rb b/app/models/account.rb index 3138d812b7c..213aed2453b 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1893,6 +1893,7 @@ class Account < ActiveRecord::Base TAB_JOBS = 15 TAB_DEVELOPER_KEYS = 16 TAB_RELEASE_NOTES = 17 + TAB_EXTENSIONS = 18 def external_tool_tabs(opts, user) tools = Lti::ContextToolFinder @@ -1956,6 +1957,11 @@ class Account < ActiveRecord::Base tabs << { id: TAB_DEVELOPER_KEYS, label: t("#account.tab_developer_keys", "Developer Keys"), css_class: "developer_keys", href: :account_developer_keys_path, account_id: root_account.id } end + if root_account? && grants_right?(user, :manage_developer_keys) && root_account.feature_enabled?(:lti_registrations_page) + registrations_path = root_account.feature_enabled?(:lti_registrations_discover_page) ? :account_lti_registrations_path : :account_lti_manage_registrations_path + tabs << { id: TAB_EXTENSIONS, label: t("#account.tab_extensions", "Extensions"), css_class: "extensions", href: registrations_path, account_id: root_account.id } + end + tabs += external_tool_tabs(opts, user) tabs += Lti::MessageHandler.lti_apps_tabs(self, [Lti::ResourcePlacement::ACCOUNT_NAVIGATION], opts) Lti::ResourcePlacement.update_tabs_and_return_item_banks_tab(tabs) diff --git a/app/views/lti_registrations/index.erb b/app/views/lti_registrations/index.erb new file mode 100644 index 00000000000..06d88cf5676 --- /dev/null +++ b/app/views/lti_registrations/index.erb @@ -0,0 +1,27 @@ +<% +# Copyright (C) 2012 - present Instructure, Inc. +# +# This file is part of Canvas. +# +# Canvas is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, version 3 of the License. +# +# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see . +%> + +<% + @show_left_side = true +%> + +<% provide :page_title do %><%= t :title, "Extensions" %><% end %> + +<% js_bundle :lti_registrations %> + +
\ No newline at end of file diff --git a/config/feature_flags/interop_release_flags.yml b/config/feature_flags/interop_release_flags.yml index 616daa66c71..c33a5d971a4 100644 --- a/config/feature_flags/interop_release_flags.yml +++ b/config/feature_flags/interop_release_flags.yml @@ -261,3 +261,22 @@ lti_placement_restrictions: state: allowed_on ci: state: allowed_on +lti_registrations_page: + state: hidden + applies_to: RootAccount + display_name: LTI Extensions Page + description: |- + When enabled, the LTI Extensions page will be available in the Account navigation. + environments: + development: + state: hidden +lti_registrations_discover_page: + state: hidden + applies_to: RootAccount + display_name: LTI Extensions Discover Page + description: |- + When enabled, the LTI Extensions Discover page will be available in the Extensions view. + environments: + development: + state: hidden + custom_transition_proc: lti_registrations_discover_page_hook diff --git a/config/routes.rb b/config/routes.rb index 67794495750..626d1c6748d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -786,6 +786,10 @@ CanvasRails::Application.routes.draw do resources :developer_keys, only: :index get "/developer_keys/:key_id", controller: :developer_keys, action: :index, as: "account_developer_key_view" + get "extensions", controller: :lti_registrations, action: :index, as: "lti_registrations" + get "extensions/*path", controller: :lti_registrations, action: :index + get "extensions/manage", controller: :lti_registrations, action: :index, as: "lti_manage_registrations" + get "release_notes" => "release_notes#manage", :as => :release_notes_manage get "blackout_dates" => "blackout_dates#index" diff --git a/lib/feature_flags/hooks.rb b/lib/feature_flags/hooks.rb index 34806c9d877..2b051a3fb04 100644 --- a/lib/feature_flags/hooks.rb +++ b/lib/feature_flags/hooks.rb @@ -143,5 +143,12 @@ module FeatureFlags ) end end + + def self.lti_registrations_discover_page_hook(_user, context, _from_state, transitions) + unless context.feature_enabled?(:lti_registrations_page) + transitions["on"] ||= {} + transitions["on"]["message"] = I18n.t("The LTI Extensions Discover page won't be accessible unless the LTI Registrations page is enabled") + end + end end end diff --git a/ui/featureBundles.ts b/ui/featureBundles.ts index ab3a3bbefab..ffb8bdff9b6 100644 --- a/ui/featureBundles.ts +++ b/ui/featureBundles.ts @@ -84,6 +84,7 @@ const featureBundles: { dashboard: () => import('./features/dashboard/index'), deep_linking_response: () => import('./features/deep_linking_response/index'), developer_keys_v2: () => import('./features/developer_keys_v2/index'), + lti_registrations: () => import('./features/lti_registrations/index'), discussion_topic_edit_v2: () => import('./features/discussion_topic_edit_v2/index'), discussion_topic_edit: () => import('./features/discussion_topic_edit/index'), discussion_topic: () => import('./features/discussion_topic/index'), diff --git a/ui/features/lti_registrations/discover/Discover.tsx b/ui/features/lti_registrations/discover/Discover.tsx new file mode 100644 index 00000000000..ffeaf1bfa54 --- /dev/null +++ b/ui/features/lti_registrations/discover/Discover.tsx @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' + +export const Discover = () => { + return ( +
+

This is the Discover page

+
+ ) +} diff --git a/ui/features/lti_registrations/discover/index.tsx b/ui/features/lti_registrations/discover/index.tsx new file mode 100644 index 00000000000..0accdd1008d --- /dev/null +++ b/ui/features/lti_registrations/discover/index.tsx @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' +import type {RouteObject} from 'react-router-dom' +import {Discover} from './Discover' + +export const DiscoverRoute: RouteObject = { + path: '/', + element: , +} diff --git a/ui/features/lti_registrations/index.tsx b/ui/features/lti_registrations/index.tsx new file mode 100644 index 00000000000..cea6caa4cb1 --- /dev/null +++ b/ui/features/lti_registrations/index.tsx @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' +import ReactDOM from 'react-dom' +import {createBrowserRouter, RouterProvider, Link} from 'react-router-dom' +import {Discover} from './discover/Discover' +import {Manage} from './manage/Manage' +import {LtiAppsLayout} from './layout/LtiAppsLayout' +import {DiscoverRoute} from './discover' +import {ManageRoute} from './manage' + +const getBasename = () => { + const path = window.location.pathname + const parts = path.split('/') + return parts.slice(0, parts.indexOf('extensions') + 1).join('/') +} + +// window.ENV.lti_registrations_discover_page + +const router = createBrowserRouter( + [ + { + path: '/', + element: , + children: window.ENV.FEATURES.lti_registrations_discover_page + ? [DiscoverRoute, ManageRoute] + : [ManageRoute], + }, + ], + { + basename: getBasename(), + } +) + +ReactDOM.render(, document.getElementById('reactContent')) diff --git a/ui/features/lti_registrations/layout/LtiAppsLayout.tsx b/ui/features/lti_registrations/layout/LtiAppsLayout.tsx new file mode 100644 index 00000000000..c416cb0117d --- /dev/null +++ b/ui/features/lti_registrations/layout/LtiAppsLayout.tsx @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' +import ReactDOM from 'react-dom' +import {createBrowserRouter, RouterProvider, Link, Outlet, useMatch} from 'react-router-dom' +import {useScope as useI18nScope} from '@canvas/i18n' +import {Heading} from '@instructure/ui-heading' +import {Spinner} from '@instructure/ui-spinner' +import {Tabs} from '@instructure/ui-tabs' +import {View} from '@instructure/ui-view' +import {Text} from '@instructure/ui-text' + +const I18n = useI18nScope('lti_registrations') + +export const LtiAppsLayout = () => { + const isManage = useMatch('/manage/*') + + return ( + <> + + {I18n.t('Extensions')} + + {I18n.t('Discover Something new or manage existing LTI extensions')} + {}}> + {window.ENV.FEATURES.lti_registrations_discover_page && ( + + {I18n.t('Discover')} + + } + > + + + )} + + {I18n.t('Manage')} + + } + id="tabA" + padding="large" + isSelected={!!isManage} + active={true} + > + + + + + ) +} diff --git a/ui/features/lti_registrations/manage/Manage.tsx b/ui/features/lti_registrations/manage/Manage.tsx new file mode 100644 index 00000000000..ec78e38761d --- /dev/null +++ b/ui/features/lti_registrations/manage/Manage.tsx @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' +import {Outlet} from 'react-router-dom' + +export const Manage = () => { + return ( +
+

This is the Manage page

+ +
+ ) +} diff --git a/ui/features/lti_registrations/manage/index.tsx b/ui/features/lti_registrations/manage/index.tsx new file mode 100644 index 00000000000..222345fd727 --- /dev/null +++ b/ui/features/lti_registrations/manage/index.tsx @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 - present Instructure, Inc. + * + * This file is part of Canvas. + * + * Canvas is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, version 3 of the License. + * + * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + */ + +import React from 'react' +import type {RouteObject} from 'react-router-dom' +import {Manage} from './Manage' + +export const ManageRoute: RouteObject = { + path: 'manage', + element: , + children: [ + { + path: 'foo', + element:
Foo
, + }, + { + path: 'bar', + element:
Bar
, + }, + ], +} diff --git a/ui/features/lti_registrations/package.json b/ui/features/lti_registrations/package.json new file mode 100644 index 00000000000..3d2a5a7be1f --- /dev/null +++ b/ui/features/lti_registrations/package.json @@ -0,0 +1,6 @@ +{ + "name": "@canvas-features/lti_registrations", + "private": true, + "version": "1.0.0", + "owner": "INTEROP" +} diff --git a/ui/shared/global/env/EnvCommon.d.ts b/ui/shared/global/env/EnvCommon.d.ts index c9f0db1c6ea..687c6f3ce97 100644 --- a/ui/shared/global/env/EnvCommon.d.ts +++ b/ui/shared/global/env/EnvCommon.d.ts @@ -216,6 +216,7 @@ export type SiteAdminFeatureId = | 'platform_service_speedgrader' | 'render_both_to_do_lists' | 'instui_header' + | 'lti_registrations_discover_page' /** * From ApplicationController#JS_ENV_ROOT_ACCOUNT_FEATURES