diff --git modules/dashboard/dashboard.info modules/dashboard/dashboard.info new file mode 100644 index 0000000..8aecfec --- /dev/null +++ modules/dashboard/dashboard.info @@ -0,0 +1,9 @@ +; $Id$ +name = Dashboard +description = A module that provides a dashboard interface for organizing and tracking various information within your site. +core = 7.x +package = Core +version = VERSION +files[] = dashboard.info +files[] = dashboard.module +dependencies[] = block diff --git modules/dashboard/dashboard.js modules/dashboard/dashboard.js new file mode 100644 index 0000000..f71a687 --- /dev/null +++ modules/dashboard/dashboard.js @@ -0,0 +1,95 @@ +// $Id: toolbar.js,v 1.1 2009/07/04 05:37:30 dries Exp $ +(function ($) { + +/** + * Implementation of Drupal.behaviors for dashboard. + */ +Drupal.behaviors.dashboard = { + attach: function () { + $('#content').append('
'); + $('#content .customize input').click(Drupal.behaviors.dashboard.showDisabledBlocks); + }, + + /** + * Enter "customize" mode. + */ + showDisabledBlocks: function () { + $('div.customize').load(Drupal.settings.dashboard.customize, Drupal.behaviors.dashboard.makeDraggable); + // Display help. + $('div#help').show(); + }, + + /** + * Helper function for showDisabledBlocks; sets up drag-and-drop. + */ + makeDraggable: function () { + // Empty dashboard regions won't render on the page, but we need them for + // drag-and drop. + var thick = $('#dashboard-thick'); + if (!thick.length) { + $('#content').after('
'); + } + var thin = $('#dashboard-thin'); + if (!thin.length) { + $('#dashboard-thick').after('
'); + } + + // Initialize drag-and-drop. + var regions = $('div.region'); + regions.sortable({ + connectWith: regions, + cursor: 'move', + dropOnEmpty: true, + items: '>div.block, div.disabled-block', + opacity: 0.8, + update: Drupal.behaviors.dashboard.update + }); + }, + + update: function (event, ui) { + var item = $(ui.item); + + // If the user dragged a disabled block, load the block contents. + if (item.hasClass('disabled-block')) { + var module, delta, itemClass; + itemClass = item.attr('class'); + // Determine the block module and delta. + module = itemClass.match(/\bmodule-(\S+)\b/)[1]; + delta = itemClass.match(/\bdelta-(\S+)\b/)[1]; + + // Load the newly enabled block's content. + $("div.content", item).load(Drupal.settings.dashboard.blockContent + '/' + module + '/' + delta); + console.log(Drupal.settings.dashboard.blockContent + '/' + module + '/' + delta); + // Remove "disabled-block" from the item's class, so we don't reload its + // content the next time it's dragged. + item.attr('class', itemClass.replace(/\bdisabled-block\b/, '')); + } + + // Let the server know what the new block order is. + $.post(Drupal.settings.dashboard.updatePath, { + 'form_token': Drupal.settings.dashboard.formToken, + 'regions': Drupal.behaviors.dashboard.getOrder + } + ); + }, + + /** + * Return the current order of the blocks in each of the sortable regions, + * in query string format. + */ + getOrder: function () { + var order = []; + $('div.region').each(function () { + var region = $(this).parent().attr('id').replace(/-/g, '_'); + var blocks = $(this).sortable('toArray'); + var i; + for (i = 0; i < blocks.length; i++) { + order.push(region + '[]=' + blocks[i]); + } + }); + order = order.join('&'); + return order; + } +}; + +})(jQuery); diff --git modules/dashboard/dashboard.module modules/dashboard/dashboard.module new file mode 100644 index 0000000..16e1d34 --- /dev/null +++ modules/dashboard/dashboard.module @@ -0,0 +1,153 @@ + 'Dashboard', + 'page callback' => 'dashboard_admin', + 'access arguments' => array('access toolbar'), + 'type' => MENU_CALLBACK, + ); + $items['admin/dashboard/customize'] = array( + 'page callback' => 'dashboard_show_disabled', + 'access arguments' => array('access toolbar'), + 'type' => MENU_CALLBACK, + ); + $items['admin/dashboard/block-content'] = array( + 'page callback' => 'dashboard_show_block_content', + 'page arguments' => array(3, 4), + 'access arguments' => array('access toolbar'), + 'type' => MENU_CALLBACK, + ); + $items['admin/dashboard/update'] = array( + 'page callback' => 'dashboard_update', + 'access arguments' => array('access toolbar'), + 'type' => MENU_CALLBACK, + ); + return $items; +} + +/** + * Implement hook_help(). + */ +function dashboard_help($path, $arg) { + switch ($path) { + case 'admin/dashboard': + return '

' . t('Drag and drop dashboard widgets to their place.') . '

'; + } +} + +/** + * Dashboard page callback. + */ +function dashboard_admin() { + drupal_add_js(drupal_get_path('module', 'dashboard') . '/dashboard.js'); + drupal_add_js(array( + 'dashboard' => array( + 'customize' => url('admin/dashboard/customize'), + 'blockContent' => url('admin/dashboard/block-content'), + 'updatePath' => url('admin/dashboard/update'), + 'formToken' => drupal_get_token('dashboard-update'), + ), + ), array('type' => 'setting')); + drupal_add_library('system', 'ui.sortable'); + drupal_add_library('system', 'ui.draggable'); + drupal_add_library('system', 'ui.droppable'); + return ''; +} + +/** + * Implement hook_block_list_alter(). + * + * Skip rendering dashboard blocks when not on the dashboard page itself. + */ +function dashboard_block_list_alter(&$blocks) { + if ($_GET['q'] != 'admin/dashboard') { + foreach ($blocks as $key => $block) { + if (strpos($block->region, 'dashboard') === 0) { + unset($blocks[$key]); + } + } + } +} + +function dashboard_show_disabled() { + global $theme_key; + + // Theme system not initialized at this point. + drupal_theme_initialize(); + + // Blocks are not necessarily initialized either. + $blocks = _block_rehash(); + + $output = '
'; + $output .= '

Disabled blocks

'; + + foreach ($blocks as $block) { + if ($block['theme'] == $theme_key && ($block['status'] == 0 || empty($block['region']))) { + $output .= '
' + . '

'.(!empty($block['title']) ? $block['title'] : $block['info']).'

' + . '
' + . '
'; + } + } + $output .= '
'; + + print $output; + exit(); + +} + +function dashboard_show_block_content($module, $delta) { + $block = module_invoke($module, 'block_view', $delta); + // TODO: Render the content portion of the block. + $rendered_block = ''; + print $rendered_block; + exit; +} + +/** + * Set the new weight of each region according to the drag-and-drop order. + */ +function dashboard_update() { + drupal_theme_initialize(); + global $theme_key; + // Check the form token to make sure we have a valid request. + if (!empty($_REQUEST['form_token']) && drupal_valid_token($_REQUEST['form_token'], 'dashboard-update')) { + parse_str($_REQUEST['regions'], $regions); + foreach ($regions as $region_name => $blocks) { + if ($region_name == 'disabled_blocks') { + $region_name = ''; + } + foreach ($blocks as $weight => $block_string) { + // Parse the query string to determine the block's module and delta. + preg_match('/block-([^-]+)-(.+)/', $block_string, $matches); + $block = new stdClass; + $block->module = $matches[1]; + $block->delta = $matches[2]; + + $block->region = $region_name; + $block->weight = $weight; + $block->status = 1; + + db_merge('block') + ->key(array( + 'module' => $block->module, + 'delta' => $block->delta, + 'theme' => $theme_key, + )) + ->fields(array( + 'status' => $block->status, + 'weight' => $block->weight, + 'region' => $block->region, + 'pages' => '', + )) + ->execute(); + } + } + } + exit; +} \ No newline at end of file diff --git modules/toolbar/toolbar.install modules/toolbar/toolbar.install index 42dadd2..edcf485 100644 --- modules/toolbar/toolbar.install +++ modules/toolbar/toolbar.install @@ -27,7 +27,7 @@ function toolbar_install() { $items = array( 'node/add' => 'Add', 'admin/content' => 'Find content', - 'admin' => 'Dashboard', + 'admin/dashboard' => 'Dashboard', ); $weight = -20; foreach ($items as $path => $title) { diff --git profiles/default/default.info profiles/default/default.info index 9ebf79a..f0fecf0 100644 --- profiles/default/default.info +++ profiles/default/default.info @@ -6,6 +6,7 @@ core = 7.x dependencies[] = block dependencies[] = color dependencies[] = comment +dependencies[] = dashboard dependencies[] = help dependencies[] = image dependencies[] = menu diff --git themes/seven/page-admin-dashboard.tpl.php themes/seven/page-admin-dashboard.tpl.php new file mode 100644 index 0000000..161c5fa --- /dev/null +++ themes/seven/page-admin-dashboard.tpl.php @@ -0,0 +1,62 @@ + +> + + <?php print $head_title; ?> + + + + + + + + + +
+ +

+
+
+ +
+
+ +
+ +
+ + +
+ +
+ + +
+ +
+
+ +
+
+ + +
+
+ +
+
+ + + + +
+ + + + + \ No newline at end of file diff --git themes/seven/seven.info themes/seven/seven.info index da9e494..f42ec45 100644 --- themes/seven/seven.info +++ themes/seven/seven.info @@ -11,3 +11,7 @@ regions[content] = Content regions[help] = Help regions[page_top] = Page top regions[page_bottom] = Page bottom +regions[dashboard_thick] = Dashboard thick +regions[dashboard_thin] = Dashboard thin +;hidden_regions[] = dashboard_thick +;hidden_regions[] = dashboard_thin diff --git themes/seven/style.css themes/seven/style.css index c402743..5e15a5e 100644 --- themes/seven/style.css +++ themes/seven/style.css @@ -728,3 +728,76 @@ body.overlay #page { body.overlay #block-system-main { padding: 20px; } + +/* Dashboard */ + +body.page-admin-dashboard div#page { + padding-top:20px; +} + +body.page-admin-dashboard div#dashboard-thick { + width: 65%; + float: left; + min-height: 1px; + margin: 5px; +} + +body.page-admin-dashboard div#dashboard-thin { + width: 30%; + float: left; + min-height: 1px; + margin: 5px; +} + +body.page-admin-dashboard div.block { + border: 1px solid #e2e1dc; + margin-bottom: 20px; +} + +body.page-admin-dashboard div.block h2 { + background-color:#e2e1dc; + padding: 3px 5px; +} + +body.page-admin-dashboard div.block div.content { + padding: 10px 5px 5px 5px; +} + +body.page-admin-dashboard div.block div.content ul.menu { + margin-left:20px; +} + +body.page-admin-dashboard.one-sidebar div#content div.block { + margin-right:20px; +} + +body.page-admin-dashboard #disabled-blocks { + margin: 5px; +} +body.page-admin-dashboard #disabled-blocks .block { + background: #e2e1dc; + padding: 4px; + margin: 3px; + display: inline; + -moz-border-radius: 4px; +} +body.page-admin-dashboard .ui-sortable { + border: 3px dashed #ccc; + padding: 10px; +} +body.page-admin-dashboard div.dragging { + width: 30% !important; +} +body.page-admin-dashboard #disabled-blocks h2 { + display: inline; + font-weight: normal; +} +body.page-admin-dashboard #disabled-blocks .block .content { + display: none; +} +body.page-admin-dashboard .ui-sortable .block { + cursor: move; +} +body.page-admin-dashboard #help { + display: none; +} \ No newline at end of file