feat: Phase 2.5 - Variant Collections Spreadsheet Editor
Replaces JSON textarea with professional Excel-like spreadsheet interface for managing product variant properties. Features: - Handsontable 14.6.1 spreadsheet component - Property presets (Size, Color, Material, Storage, Custom) - Inline cell editing with Tab/Enter navigation - Context menu for add/remove rows and columns - Keyboard shortcuts (Ctrl+D delete, Ctrl+Enter save, Ctrl+Z undo) - Mobile touch gestures (swipe to delete rows) - Automatic JSON serialization on form submit - Form validation before saving - Comprehensive user guide documentation Files Changed: - LittleShop/package.json: NPM package management setup - LittleShop/wwwroot/js/variant-editor.js: 400-line spreadsheet editor module - LittleShop/wwwroot/lib/handsontable/: Handsontable library (Community Edition) - LittleShop/wwwroot/lib/hammerjs/: Hammer.js touch gesture library - LittleShop/Areas/Admin/Views/VariantCollections/Edit.cshtml: Spreadsheet UI integration - VARIANT_COLLECTIONS_USER_GUIDE.md: Complete user guide (18+ pages) Technical Details: - Excel-like editing experience (no more manual JSON editing) - Mobile-first responsive design - Browser compatibility: Chrome 90+, Firefox 88+, Edge 90+, Safari 14+ - Touch-optimized for mobile administration - Automatic data validation and error handling
This commit is contained in:
124
LittleShop/wwwroot/lib/hammerjs/Gruntfile.coffee
Normal file
124
LittleShop/wwwroot/lib/hammerjs/Gruntfile.coffee
Normal file
@@ -0,0 +1,124 @@
|
||||
module.exports = (grunt) ->
|
||||
grunt.initConfig
|
||||
pkg: grunt.file.readJSON 'package.json'
|
||||
|
||||
usebanner:
|
||||
taskName:
|
||||
options:
|
||||
position: 'top'
|
||||
banner: '
|
||||
/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n
|
||||
* <%= pkg.homepage %>\n
|
||||
*\n
|
||||
* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;\n
|
||||
* Licensed under the <%= pkg.license %> license */'
|
||||
linebreak: true
|
||||
files:
|
||||
src: ['./hammer.js','./hammer.min.js']
|
||||
|
||||
concat:
|
||||
build:
|
||||
src: [
|
||||
'src/hammer.prefix.js'
|
||||
'src/utils.js'
|
||||
'src/input.js'
|
||||
'src/input/*.js'
|
||||
'src/touchaction.js'
|
||||
'src/recognizer.js'
|
||||
'src/recognizers/*.js'
|
||||
'src/hammer.js'
|
||||
'src/manager.js'
|
||||
'src/expose.js'
|
||||
'src/hammer.suffix.js']
|
||||
dest: 'hammer.js'
|
||||
|
||||
uglify:
|
||||
min:
|
||||
options:
|
||||
report: 'gzip'
|
||||
sourceMap: 'hammer.min.map'
|
||||
files:
|
||||
'hammer.min.js': ['hammer.js']
|
||||
# special test build that exposes everything so it's testable
|
||||
test:
|
||||
options:
|
||||
wrap: "$H"
|
||||
comments: 'all'
|
||||
exportAll: true
|
||||
mangle: false
|
||||
beautify: true
|
||||
compress:
|
||||
global_defs:
|
||||
exportName: 'Hammer'
|
||||
files:
|
||||
'tests/build.js': [
|
||||
'src/utils.js'
|
||||
'src/input.js'
|
||||
'src/input/*.js'
|
||||
'src/touchaction.js'
|
||||
'src/recognizer.js'
|
||||
'src/recognizers/*.js'
|
||||
'src/hammer.js'
|
||||
'src/manager.js'
|
||||
'src/expose.js']
|
||||
|
||||
'string-replace':
|
||||
version:
|
||||
files:
|
||||
'hammer.js': 'hammer.js'
|
||||
options:
|
||||
replacements: [
|
||||
pattern: '{{PKG_VERSION}}'
|
||||
replacement: '<%= pkg.version %>'
|
||||
]
|
||||
|
||||
jshint:
|
||||
options:
|
||||
jshintrc: true
|
||||
build:
|
||||
src: ['hammer.js']
|
||||
|
||||
jscs:
|
||||
src: [
|
||||
'src/**/*.js',
|
||||
'!src/hammer.prefix.js',
|
||||
'!src/hammer.suffix.js'
|
||||
]
|
||||
options:
|
||||
config: "./.jscsrc"
|
||||
force: true
|
||||
|
||||
watch:
|
||||
scripts:
|
||||
files: ['src/**/*.js']
|
||||
tasks: ['concat','string-replace','uglify','jshint','jscs']
|
||||
options:
|
||||
interrupt: true
|
||||
|
||||
connect:
|
||||
server:
|
||||
options:
|
||||
hostname: "0.0.0.0"
|
||||
port: 8000
|
||||
|
||||
qunit:
|
||||
all: ['tests/unit/index.html']
|
||||
|
||||
|
||||
# Load tasks
|
||||
grunt.loadNpmTasks 'grunt-contrib-concat'
|
||||
grunt.loadNpmTasks 'grunt-contrib-uglify'
|
||||
grunt.loadNpmTasks 'grunt-contrib-qunit'
|
||||
grunt.loadNpmTasks 'grunt-contrib-watch'
|
||||
grunt.loadNpmTasks 'grunt-contrib-jshint'
|
||||
grunt.loadNpmTasks 'grunt-contrib-connect'
|
||||
grunt.loadNpmTasks 'grunt-string-replace'
|
||||
grunt.loadNpmTasks 'grunt-banner'
|
||||
grunt.loadNpmTasks 'grunt-jscs'
|
||||
|
||||
# Default task(s)
|
||||
grunt.registerTask 'default', ['connect', 'watch']
|
||||
grunt.registerTask 'default-test', ['connect', 'uglify:test', 'watch']
|
||||
grunt.registerTask 'build', ['concat', 'string-replace', 'uglify:min', 'usebanner', 'test']
|
||||
grunt.registerTask 'test', ['jshint', 'jscs', 'uglify:test', 'qunit']
|
||||
grunt.registerTask 'test-travis', ['build']
|
||||
Reference in New Issue
Block a user