diff options
Diffstat (limited to 'src/client/views/collections')
16 files changed, 1625 insertions, 975 deletions
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss index f04b19ef7..c35f088a6 100644 --- a/src/client/views/collections/CollectionMenu.scss +++ b/src/client/views/collections/CollectionMenu.scss @@ -1,628 +1,659 @@ @import "../global/globalCssVariables"; -.collectionMenu-cont { - position: relative; - display: inline-flex; - width: 100%; - opacity: 0.9; - z-index: 901; - transition: top .5s; - background: $dark-gray; - color: $white; - transform-origin: top left; - top: 0; - width: 100%; - - .recordButtonOutline { - border-radius: 100%; - width: 18px; - height: 18px; - border: solid 1px $white; - display: flex; - align-items: center; - justify-content: center; - } - - .recordButtonInner { - border-radius: 100%; - width: 70%; - height: 70%; - background: $white; - } - - .collectionMenu { - display: flex; - height: 100%; - overflow: visible; - z-index: 901; - border: unset; - - .collectionMenu-divider { - height: 100%; - margin-left: 3px; - margin-right: 3px; - width: 2px; - background-color: $medium-gray; - } - - .collectionViewBaseChrome { - display: flex; - align-items: center; - - .collectionViewBaseChrome-viewPicker { - font-size: $small-text; - outline-color: $black; - color: $white; - border: none; - background: $dark-gray; - } - - .collectionViewBaseChrome-viewPicker:focus { - outline: none; - border: none; - } - - .collectionViewBaseChrome-viewPicker:active { - outline-color: $black; - } - - .collectionViewBaseChrome-button { - font-size: $small-text; - text-transform: uppercase; - letter-spacing: 2px; - background: $white; - color: $pink; - outline-color: $black; - border: none; - padding: 12px 10px 11px 10px; - margin-left: 10px; - } - - .collectionViewBaseChrome-cmdPicker { - margin-left: 3px; - margin-right: 0px; - font-size: $small-text; - text-transform: capitalize; - color: $white; - border: none; - background: $dark-gray; - } - - .collectionViewBaseChrome-cmdPicker:focus { - border: none; - outline: none; - } - - .commandEntry-outerDiv { - pointer-events: all; - background-color: transparent; - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - height: 100%; - overflow: hidden; - - .commandEntry-drop { - color: $white; - width: 30px; - margin-top: auto; - margin-bottom: auto; - } - } - - .commandEntry-outerDiv:hover{ - background-color: $drop-shadow; - - .collectionViewBaseChrome-viewPicker, - .collectionViewBaseChrome-cmdPicker{ - background: $dark-gray; - } - } - - .collectionViewBaseChrome-collapse { - transition: all .5s, opacity 0.3s; - position: absolute; - width: 30px; - transform-origin: top left; - pointer-events: all; - // margin-top: 10px; - } - - @media only screen and (max-device-width: 480px) { - .collectionViewBaseChrome-collapse { - display: none; - } - } - - .collectionViewBaseChrome-template, - .collectionViewBaseChrome-viewModes { - align-items: center; - height: 100%; - display: flex; - background: transparent; - color: $medium-gray; - justify-content: center; - } - - .collectionViewBaseChrome-viewSpecs { - margin-left: 5px; - display: grid; - border: none; - border-right: solid $medium-gray 1px; - - .collectionViewBaseChrome-filterIcon { - position: relative; - display: flex; - margin: auto; - background: $dark-gray; - color: $white; - width: 30px; - height: 30px; - align-items: center; - justify-content: center; - border: none; - border-right: solid $medium-gray 1px; - } - - .collectionViewBaseChrome-viewSpecsInput { - padding: 12px 10px 11px 10px; - border: 0px; - color: $medium-gray; - text-align: center; - letter-spacing: 2px; - outline-color: $black; - font-size: $small-text; - background: $white; - height: 100%; - width: 75px; - } - - .collectionViewBaseChrome-viewSpecsMenu { - overflow: hidden; - transition: height .5s, display .5s; - position: absolute; - top: 60px; - z-index: 100; - display: flex; - flex-direction: column; - background: $white; - box-shadow: $medium-gray 2px 2px 4px; - - .qs-datepicker { - left: unset; - right: 0; - } - - .collectionViewBaseChrome-viewSpecsMenu-row { - display: grid; - grid-template-columns: 150px 200px 150px; - margin-top: 10px; - margin-right: 10px; - - .collectionViewBaseChrome-viewSpecsMenu-rowLeft, - .collectionViewBaseChrome-viewSpecsMenu-rowMiddle, - .collectionViewBaseChrome-viewSpecsMenu-rowRight { - font-size: $small-text; - letter-spacing: 2px; - color: $medium-gray; - margin-left: 10px; - padding: 5px; - border: none; - outline-color: $black; - } - } - - .collectionViewBaseChrome-viewSpecsMenu-lastRow { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-gap: 10px; - margin: 10px; - } - } - } - } - - .collectionStackingViewChrome-cont, - .collectionTreeViewChrome-cont, - .collection3DCarouselViewChrome-cont { - display: flex; - justify-content: space-between; - } - - .collectionGridViewChrome-cont { - display: flex; - margin-left: 10; - - .collectionGridViewChrome-viewPicker { - font-size: $small-text; - //text-transform: uppercase; - //letter-spacing: 2px; - background: $dark-gray; - color: $white; - outline-color: $black; - color: $white; - border: none; - border-right: solid $medium-gray 1px; - } - - .collectionGridViewChrome-viewPicker:active { - outline-color: $black; - } - - .grid-control { - align-self: center; - display: flex; - flex-direction: row; - margin-right: 5px; - - .grid-icon { - margin-right: 5px; - align-self: center; - } - - .flexLabel { - margin-bottom: 0; - } - - .collectionGridViewChrome-entryBox { - width: 50%; - color: $black; - } - - .collectionGridViewChrome-columnButton { - color: $black; - } - } - } - - .collectionStackingViewChrome-sort, - .collectionTreeViewChrome-sort { - display: flex; - align-items: center; - justify-content: space-between; - - .collectionStackingViewChrome-sortIcon, - .collectionTreeViewChrome-sortIcon { - transition: transform .5s; - margin-left: 10px; - } - } - - button:hover { - transform: scale(1); - } - - - .collectionStackingViewChrome-pivotField-cont, - .collectionTreeViewChrome-pivotField-cont, - .collection3DCarouselViewChrome-scrollSpeed-cont { - justify-self: right; - align-items: center; - display: flex; - grid-auto-columns: auto; - font-size: $small-text; - letter-spacing: 2px; - - .collectionStackingViewChrome-pivotField-label, - .collectionTreeViewChrome-pivotField-label, - .collection3DCarouselViewChrome-scrollSpeed-label { - grid-column: 1; - margin-right: 7px; - user-select: none; - font-family: $sans-serif; - letter-spacing: normal; - } - - .collectionStackingViewChrome-sortIcon { - transition: transform .5s; - grid-column: 3; - text-align: center; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - width: 25px; - height: 25px; - border-radius: 100%; - } - - .collectionStackingViewChrome-sortIcon:hover { - background-color: $drop-shadow; - } - - .collectionStackingViewChrome-pivotField, - .collectionTreeViewChrome-pivotField, - .collection3DCarouselViewChrome-scrollSpeed { - color: $white; - grid-column: 2; - grid-row: 1; - width: 90%; - min-width: 100px; - display: flex; - height: 80%; - border-radius: 7px; - align-items: center; - background: $white; - - .editable-view-input, - input, - .editableView-container-editing-oneLine, - .editableView-container-editing { - margin: auto; - border: 0px; - color: $light-gray !important; - text-align: center; - letter-spacing: 2px; - outline-color: $black; - height: 100%; - } - - .react-autosuggest__container { - margin: 0; - color: $medium-gray; - padding: 0px; - } - } - } - - .collectionStackingViewChrome-pivotField:hover, - .collectionTreeViewChrome-pivotField:hover, - .collection3DCarouselViewChrome-scrollSpeed:hover { - cursor: text; - } - - } -} - -.collectionMenu-webUrlButtons { - margin-left: 44; - background: lightGray; +.collectionMenu-container { display: flex; -} - -.webBox-urlEditor { - position: relative; - opacity: 0.9; - z-index: 901; - transition: top .5s; - - .urlEditor { - display: grid; - grid-template-columns: 1fr auto; - padding-bottom: 10px; - overflow: hidden; - margin-top: 5px; - height: 35px; - - .editorBase { - display: flex; - - .editor-collapse { - transition: all .5s, opacity 0.3s; - position: absolute; - width: 40px; - transform-origin: top left; - } - - .switchToText { - color: $medium-gray; - } - - .switchToText:hover { - color: $dark-gray; - } - } - - button:hover { - transform: scale(1); - } - } -} - -.collectionMenu-urlInput { - padding: 12px 10px 11px 10px; - border: 0px; - color: $black; - font-size: $small-text; - letter-spacing: 2px; - outline-color: $black; - background: $white; - width: 100%; - min-width: 350px; - margin-right: 10px; - height: 100%; -} - -.collectionFreeFormMenu-cont { - display: inline-flex; position: relative; + align-content: center; + justify-content: space-between; + background-color: $dark-gray; + height: 35px; + border-bottom: $standard-border; + padding-right: 5px; align-items: center; - height: 100%; - - .color-previewI { - width: 60%; - top: 80%; - position: absolute; - height: 4px; - } - - .color-previewII { - width: 80%; - height: 80%; - margin-left: 10%; - position: absolute; - bottom: 5; - } - - .btn-group { - display: grid; - grid-template-columns: auto auto auto auto; - margin: auto; - /* Make the buttons appear below each other */ - } - .btn-draw { - display: inline-flex; - margin: auto; - /* Make the buttons appear below each other */ - } - - .fwdKeyframe, - .numKeyframe, - .backKeyframe { + .collectionMenu-hardCodedButton { cursor: pointer; - position: relative; - width: 20; - height: 30; - bottom: 0; - background: $dark-gray; - display: inline-flex; - align-items: center; color: $white; - } - - .backKeyframe { - svg { - display: block; - margin: auto; - } - } - - - .numKeyframe { - flex-direction: column; - padding-top: 5px; - } - - .fwdKeyframe { - svg { - display: block; - margin: auto; - } - - border-right: solid $medium-gray 1px; - } -} - -.collectionSchemaViewChrome-cont { - display: flex; - font-size: $small-text; - - .collectionSchemaViewChrome-toggle { - display: flex; - margin-left: 10px; - } - - .collectionSchemaViewChrome-label { - text-transform: uppercase; - letter-spacing: 2px; - margin-right: 5px; + width: 25px; + height: 25px; + padding: 5; + text-align: center; display: flex; - flex-direction: column; justify-content: center; - } - - .collectionSchemaViewChrome-toggler { - width: 100px; - height: 35px; - background-color: $black; + align-items: center; position: relative; - } - - .collectionSchemaViewChrome-togglerButton { - width: 47px; - height: 30px; - background-color: $light-gray; - // position: absolute; - transition: all 0.5s ease; - // top: 3px; - margin-top: 3px; - color: $medium-gray; - letter-spacing: 2px; - text-transform: uppercase; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; + transition: 0.2s; + border-radius: 3px; - &.on { - margin-left: 3px; - } - - &.off { - margin-left: 50px; + &:hover { + background-color: rgba(0, 0, 0, 0.2); } } } - -.commandEntry-outerDiv { - display: flex; - flex-direction: column; - height: 40px; -} - -.commandEntry-inputArea { - display: flex; - flex-direction: row; - width: 150px; - margin: auto auto auto auto; -} - -.react-autosuggest__container { - position: relative; - width: 100%; - margin-left: 5px; - margin-right: 5px; -} - -.react-autosuggest__input { - border: 1px solid $light-gray; - border-radius: 4px; - width: 100%; -} - -.react-autosuggest__input--focused { - outline: none; -} - -.react-autosuggest__input--open { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.react-autosuggest__suggestions-container { - display: none; -} - -.react-autosuggest__suggestions-container--open { - display: block; - position: fixed; - overflow-y: auto; - max-height: 400px; - width: 180px; - border: 1px solid $light-gray; - background-color: $white; - font-family: $sans-serif; - font-weight: 300; - font-size: $large-header; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - z-index: 2; -} - -.react-autosuggest__suggestions-list { - margin: 0; - padding: 0; - list-style-type: none; -} - -.react-autosuggest__suggestion { - cursor: pointer; - padding: 10px 20px; -} - -.react-autosuggest__suggestion--highlighted { - background-color: $light-gray; -}
\ No newline at end of file +// .collectionMenu-cont { +// position: relative; +// display: inline-flex; +// width: 100%; +// opacity: 0.9; +// z-index: 901; +// transition: top .5s; +// background: $dark-gray; +// color: $white; +// transform-origin: top left; +// top: 0; +// width: 100%; + +// .recordButtonOutline { +// border-radius: 100%; +// width: 18px; +// height: 18px; +// border: solid 1px $white; +// display: flex; +// align-items: center; +// justify-content: center; +// } + +// .recordButtonInner { +// border-radius: 100%; +// width: 70%; +// height: 70%; +// background: $white; +// } + +// .collectionMenu { +// display: flex; +// height: 100%; +// overflow: visible; +// z-index: 901; +// border: unset; + +// .collectionMenu-divider { +// height: 100%; +// margin-left: 3px; +// margin-right: 3px; +// width: 2px; +// background-color: $medium-gray; +// } + +// .collectionViewBaseChrome { +// display: flex; +// align-items: center; + +// .collectionViewBaseChrome-viewPicker { +// font-size: $small-text; +// outline-color: $black; +// color: $white; +// border: none; +// background: $dark-gray; +// } + +// .collectionViewBaseChrome-viewPicker:focus { +// outline: none; +// border: none; +// } + +// .collectionViewBaseChrome-viewPicker:active { +// outline-color: $black; +// } + +// .collectionViewBaseChrome-button { +// font-size: $small-text; +// text-transform: uppercase; +// letter-spacing: 2px; +// background: $white; +// color: $pink; +// outline-color: $black; +// border: none; +// padding: 12px 10px 11px 10px; +// margin-left: 10px; +// } + +// .collectionViewBaseChrome-cmdPicker { +// margin-left: 3px; +// margin-right: 0px; +// font-size: $small-text; +// text-transform: capitalize; +// color: $white; +// border: none; +// background: $dark-gray; +// } + +// .collectionViewBaseChrome-cmdPicker:focus { +// border: none; +// outline: none; +// } + +// .commandEntry-outerDiv { +// pointer-events: all; +// background-color: transparent; +// display: flex; +// flex-direction: row; +// align-items: center; +// justify-content: center; +// height: 100%; +// overflow: hidden; + +// .commandEntry-drop { +// color: $white; +// width: 30px; +// margin-top: auto; +// margin-bottom: auto; +// } +// } + +// .commandEntry-outerDiv:hover{ +// background-color: $drop-shadow; + +// .collectionViewBaseChrome-viewPicker, +// .collectionViewBaseChrome-cmdPicker{ +// background: $dark-gray; +// } +// } + +// .collectionViewBaseChrome-collapse { +// transition: all .5s, opacity 0.3s; +// position: absolute; +// width: 30px; +// transform-origin: top left; +// pointer-events: all; +// // margin-top: 10px; +// } + +// @media only screen and (max-device-width: 480px) { +// .collectionViewBaseChrome-collapse { +// display: none; +// } +// } + +// .collectionViewBaseChrome-template, +// .collectionViewBaseChrome-viewModes { +// align-items: center; +// height: 100%; +// display: flex; +// background: transparent; +// color: $medium-gray; +// justify-content: center; +// } + +// .collectionViewBaseChrome-viewSpecs { +// margin-left: 5px; +// display: grid; +// border: none; +// border-right: solid $medium-gray 1px; + +// .collectionViewBaseChrome-filterIcon { +// position: relative; +// display: flex; +// margin: auto; +// background: $dark-gray; +// color: $white; +// width: 30px; +// height: 30px; +// align-items: center; +// justify-content: center; +// border: none; +// border-right: solid $medium-gray 1px; +// } + +// .collectionViewBaseChrome-viewSpecsInput { +// padding: 12px 10px 11px 10px; +// border: 0px; +// color: $medium-gray; +// text-align: center; +// letter-spacing: 2px; +// outline-color: $black; +// font-size: $small-text; +// background: $white; +// height: 100%; +// width: 75px; +// } + +// .collectionViewBaseChrome-viewSpecsMenu { +// overflow: hidden; +// transition: height .5s, display .5s; +// position: absolute; +// top: 60px; +// z-index: 100; +// display: flex; +// flex-direction: column; +// background: $white; +// box-shadow: $medium-gray 2px 2px 4px; + +// .qs-datepicker { +// left: unset; +// right: 0; +// } + +// .collectionViewBaseChrome-viewSpecsMenu-row { +// display: grid; +// grid-template-columns: 150px 200px 150px; +// margin-top: 10px; +// margin-right: 10px; + +// .collectionViewBaseChrome-viewSpecsMenu-rowLeft, +// .collectionViewBaseChrome-viewSpecsMenu-rowMiddle, +// .collectionViewBaseChrome-viewSpecsMenu-rowRight { +// font-size: $small-text; +// letter-spacing: 2px; +// color: $medium-gray; +// margin-left: 10px; +// padding: 5px; +// border: none; +// outline-color: $black; +// } +// } + +// .collectionViewBaseChrome-viewSpecsMenu-lastRow { +// display: grid; +// grid-template-columns: 1fr 1fr 1fr; +// grid-gap: 10px; +// margin: 10px; +// } +// } +// } +// } + +// .collectionStackingViewChrome-cont, +// .collectionTreeViewChrome-cont, +// .collection3DCarouselViewChrome-cont { +// display: flex; +// justify-content: space-between; +// } + +// .collectionGridViewChrome-cont { +// display: flex; +// margin-left: 10; + +// .collectionGridViewChrome-viewPicker { +// font-size: $small-text; +// //text-transform: uppercase; +// //letter-spacing: 2px; +// background: $dark-gray; +// color: $white; +// outline-color: $black; +// color: $white; +// border: none; +// border-right: solid $medium-gray 1px; +// } + +// .collectionGridViewChrome-viewPicker:active { +// outline-color: $black; +// } + +// .grid-control { +// align-self: center; +// display: flex; +// flex-direction: row; +// margin-right: 5px; + +// .grid-icon { +// margin-right: 5px; +// align-self: center; +// } + +// .flexLabel { +// margin-bottom: 0; +// } + +// .collectionGridViewChrome-entryBox { +// width: 50%; +// color: $black; +// } + +// .collectionGridViewChrome-columnButton { +// color: $black; +// } +// } +// } + +// .collectionStackingViewChrome-sort, +// .collectionTreeViewChrome-sort { +// display: flex; +// align-items: center; +// justify-content: space-between; + +// .collectionStackingViewChrome-sortIcon, +// .collectionTreeViewChrome-sortIcon { +// transition: transform .5s; +// margin-left: 10px; +// } +// } + +// button:hover { +// transform: scale(1); +// } + + +// .collectionStackingViewChrome-pivotField-cont, +// .collectionTreeViewChrome-pivotField-cont, +// .collection3DCarouselViewChrome-scrollSpeed-cont { +// justify-self: right; +// align-items: center; +// display: flex; +// grid-auto-columns: auto; +// font-size: $small-text; +// letter-spacing: 2px; + +// .collectionStackingViewChrome-pivotField-label, +// .collectionTreeViewChrome-pivotField-label, +// .collection3DCarouselViewChrome-scrollSpeed-label { +// grid-column: 1; +// margin-right: 7px; +// user-select: none; +// font-family: $sans-serif; +// letter-spacing: normal; +// } + +// .collectionStackingViewChrome-sortIcon { +// transition: transform .5s; +// grid-column: 3; +// text-align: center; +// display: flex; +// justify-content: center; +// align-items: center; +// cursor: pointer; +// width: 25px; +// height: 25px; +// border-radius: 100%; +// } + +// .collectionStackingViewChrome-sortIcon:hover { +// background-color: $drop-shadow; +// } + +// .collectionStackingViewChrome-pivotField, +// .collectionTreeViewChrome-pivotField, +// .collection3DCarouselViewChrome-scrollSpeed { +// color: $white; +// grid-column: 2; +// grid-row: 1; +// width: 90%; +// min-width: 100px; +// display: flex; +// height: 80%; +// border-radius: 7px; +// align-items: center; +// background: $white; + +// .editable-view-input, +// input, +// .editableView-container-editing-oneLine, +// .editableView-container-editing { +// margin: auto; +// border: 0px; +// color: $light-gray !important; +// text-align: center; +// letter-spacing: 2px; +// outline-color: $black; +// height: 100%; +// } + +// .react-autosuggest__container { +// margin: 0; +// color: $medium-gray; +// padding: 0px; +// } +// } +// } + +// .collectionStackingViewChrome-pivotField:hover, +// .collectionTreeViewChrome-pivotField:hover, +// .collection3DCarouselViewChrome-scrollSpeed:hover { +// cursor: text; +// } + +// } +// } + +// .collectionMenu-webUrlButtons { +// margin-left: 44; +// background: lightGray; +// display: flex; +// } + +// .webBox-urlEditor { +// position: relative; +// opacity: 0.9; +// z-index: 901; +// transition: top .5s; + +// .urlEditor { +// display: grid; +// grid-template-columns: 1fr auto; +// padding-bottom: 10px; +// overflow: hidden; +// margin-top: 5px; +// height: 35px; + +// .editorBase { +// display: flex; + +// .editor-collapse { +// transition: all .5s, opacity 0.3s; +// position: absolute; +// width: 40px; +// transform-origin: top left; +// } + +// .switchToText { +// color: $medium-gray; +// } + +// .switchToText:hover { +// color: $dark-gray; +// } +// } + +// button:hover { +// transform: scale(1); +// } +// } +// } + +// .collectionMenu-urlInput { +// padding: 12px 10px 11px 10px; +// border: 0px; +// color: $black; +// font-size: $small-text; +// letter-spacing: 2px; +// outline-color: $black; +// background: $white; +// width: 100%; +// min-width: 350px; +// margin-right: 10px; +// height: 100%; +// } + +// .collectionFreeFormMenu-cont { +// display: inline-flex; +// position: relative; +// align-items: center; +// height: 100%; + +// .color-previewI { +// width: 60%; +// top: 80%; +// position: absolute; +// height: 4px; +// } + +// .color-previewII { +// width: 80%; +// height: 80%; +// margin-left: 10%; +// position: absolute; +// bottom: 5; +// } + +// .btn-group { +// display: grid; +// grid-template-columns: auto auto auto auto; +// margin: auto; +// /* Make the buttons appear below each other */ +// } + +// .btn-draw { +// display: inline-flex; +// margin: auto; +// /* Make the buttons appear below each other */ +// } + +// .fwdKeyframe, +// .numKeyframe, +// .backKeyframe { +// cursor: pointer; +// position: relative; +// width: 20; +// height: 30; +// bottom: 0; +// background: $dark-gray; +// display: inline-flex; +// align-items: center; +// color: $white; +// } + +// .backKeyframe { +// svg { +// display: block; +// margin: auto; +// } +// } + + +// .numKeyframe { +// flex-direction: column; +// padding-top: 5px; +// } + +// .fwdKeyframe { +// svg { +// display: block; +// margin: auto; +// } + +// border-right: solid $medium-gray 1px; +// } +// } + +// .collectionSchemaViewChrome-cont { +// display: flex; +// font-size: $small-text; + +// .collectionSchemaViewChrome-toggle { +// display: flex; +// margin-left: 10px; +// } + +// .collectionSchemaViewChrome-label { +// text-transform: uppercase; +// letter-spacing: 2px; +// margin-right: 5px; +// display: flex; +// flex-direction: column; +// justify-content: center; +// } + +// .collectionSchemaViewChrome-toggler { +// width: 100px; +// height: 35px; +// background-color: $black; +// position: relative; +// } + +// .collectionSchemaViewChrome-togglerButton { +// width: 47px; +// height: 30px; +// background-color: $light-gray; +// // position: absolute; +// transition: all 0.5s ease; +// // top: 3px; +// margin-top: 3px; +// color: $medium-gray; +// letter-spacing: 2px; +// text-transform: uppercase; +// display: flex; +// flex-direction: column; +// justify-content: center; +// text-align: center; + +// &.on { +// margin-left: 3px; +// } + +// &.off { +// margin-left: 50px; +// } +// } +// } + + +// .commandEntry-outerDiv { +// display: flex; +// flex-direction: column; +// height: 40px; +// } + +// .commandEntry-inputArea { +// display: flex; +// flex-direction: row; +// width: 150px; +// margin: auto auto auto auto; +// } + +// .react-autosuggest__container { +// position: relative; +// width: 100%; +// margin-left: 5px; +// margin-right: 5px; +// } + +// .react-autosuggest__input { +// border: 1px solid $light-gray; +// border-radius: 4px; +// width: 100%; +// } + +// .react-autosuggest__input--focused { +// outline: none; +// } + +// .react-autosuggest__input--open { +// border-bottom-left-radius: 0; +// border-bottom-right-radius: 0; +// } + +// .react-autosuggest__suggestions-container { +// display: none; +// } + +// .react-autosuggest__suggestions-container--open { +// display: block; +// position: fixed; +// overflow-y: auto; +// max-height: 400px; +// width: 180px; +// border: 1px solid $light-gray; +// background-color: $white; +// font-family: $sans-serif; +// font-weight: 300; +// font-size: $large-header; +// border-bottom-left-radius: 4px; +// border-bottom-right-radius: 4px; +// z-index: 2; +// } + +// .react-autosuggest__suggestions-list { +// margin: 0; +// padding: 0; +// list-style-type: none; +// } + +// .react-autosuggest__suggestion { +// cursor: pointer; +// padding: 10px 20px; +// } + +// .react-autosuggest__suggestion--highlighted { +// background-color: $light-gray; +// }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index 8f4df4a92..cbfe47338 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -15,29 +15,32 @@ import { RichTextField } from "../../../fields/RichTextField"; import { listSpec } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; -import { emptyFunction, setupMoveUpEvents, Utils } from "../../../Utils"; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils"; +import { Docs } from "../../documents/Documents"; import { DocumentType } from "../../documents/DocumentTypes"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { DragManager } from "../../util/DragManager"; import { Scripting } from "../../util/Scripting"; import { SelectionManager } from "../../util/SelectionManager"; +import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu"; import { EditableView } from "../EditableView"; import { GestureOverlay } from "../GestureOverlay"; -import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, ActiveArrowStart, ActiveArrowEnd } from "../InkingStroke"; +import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from "../InkingStroke"; +import { LightboxView } from "../LightboxView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; +import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; import { RichTextMenu } from "../nodes/formattedText/RichTextMenu"; import { PresBox } from "../nodes/trails/PresBox"; +import { DefaultStyleProvider } from "../StyleProvider"; +import { CollectionDockingView } from "./CollectionDockingView"; +import { CollectionLinearView } from "./CollectionLinearView"; import "./CollectionMenu.scss"; import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { TabDocView } from "./TabDocView"; -import { LightboxView } from "../LightboxView"; -import { Docs } from "../../documents/Documents"; -import { DocumentManager } from "../../util/DocumentManager"; -import { CollectionDockingView } from "./CollectionDockingView"; -import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox"; +import { Colors } from "../global/globalEnums"; @observer export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> { @@ -46,6 +49,8 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> { @observable SelectedCollection: DocumentView | undefined; @observable FieldKey: string; + private _docBtnRef = React.createRef<HTMLDivElement>(); + constructor(props: any) { super(props); this.FieldKey = ""; @@ -82,30 +87,88 @@ export class CollectionMenu extends AntimodeMenu<AntimodeMenuProps> { } } + buttonBarXf = () => { + if (!this._docBtnRef.current) return Transform.Identity(); + const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current); + return new Transform(-translateX, -translateY, 1 / scale); + } + + @computed get contMenuButtons() { + const selDoc = Doc.UserDoc().contextMenuBtns; + return !(selDoc instanceof Doc) ? (null) : <div className="collectionMenu-contMenuButtons" ref={this._docBtnRef} style={{ height: "35px" }} > + <CollectionLinearView + Document={selDoc} + DataDoc={undefined} + fieldKey={"data"} + dropAction={"alias"} + setHeight={returnFalse} + styleProvider={DefaultStyleProvider} + layerProvider={undefined} + rootSelected={returnTrue} + bringToFront={emptyFunction} + select={emptyFunction} + isContentActive={returnFalse} + isAnyChildContentActive={returnFalse} + isSelected={returnFalse} + docViewPath={returnEmptyDoclist} + moveDocument={returnFalse} + CollectionView={undefined} + addDocument={returnFalse} + addDocTab={returnFalse} + pinToPres={emptyFunction} + removeDocument={returnFalse} + ScreenToLocalTransform={this.buttonBarXf} + PanelWidth={() => 100} + PanelHeight={() => 35} + renderDepth={0} + focus={emptyFunction} + whenChildContentsActiveChanged={emptyFunction} + docFilters={returnEmptyFilter} + docRangeFilters={returnEmptyFilter} + searchFilterDocs={returnEmptyDoclist} + ContainingCollectionView={undefined} + ContainingCollectionDoc={undefined} /> + </div>; + } + render() { - const button = <Tooltip title={<div className="dash-tooltip">Pin Menu</div>} key="pin menu" placement="bottom"> - <button className="antimodeMenu-button" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}> - <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} /> - </button> - </Tooltip>; const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left"; const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Properties Panel" : "Open Properties Panel"; const prop = <Tooltip title={<div className="dash-tooltip">{propTitle}</div>} key="properties" placement="bottom"> - <button className="antimodeMenu-button" key="properties" style={{ backgroundColor: "#424242" }} + <div className="collectionMenu-hardCodedButton" + style={{ backgroundColor: CurrentUserUtils.propertiesWidth > 0 ? Colors.MEDIUM_BLUE : undefined }} + key="properties" onPointerDown={this.toggleProperties}> <FontAwesomeIcon icon={propIcon} size="lg" /> - </button> + </div> </Tooltip>; - return this.getElement(!this.SelectedCollection ? [/*button*/] : - [<CollectionViewBaseChrome key="chrome" - docView={this.SelectedCollection} - fieldKey={this.SelectedCollection.LayoutFieldKey} - type={StrCast(this.SelectedCollection?.props.Document._viewType, CollectionViewType.Invalid) as CollectionViewType} />, - prop, - /*button*/]); + // NEW BUTTONS + //dash col linear view buttons + const contMenuButtons = + <div className="collectionMenu-container"> + {this.contMenuButtons} + {prop} + </div>; + + return contMenuButtons; + + // const button = <Tooltip title={<div className="dash-tooltip">Pin Menu</div>} key="pin menu" placement="bottom"> + // <button className="antimodeMenu-button" onClick={this.toggleMenuPin} style={{ backgroundColor: "#121721" }}> + // <FontAwesomeIcon icon="thumbtack" size="lg" style={{ transitionProperty: "transform", transitionDuration: "0.1s", transform: `rotate(${this.Pinned ? 45 : 0}deg)` }} /> + // </button> + // </Tooltip>; + + // OLD BUTTONS + // return this.getElement(!this.SelectedCollection ? [/*button*/] : + // [<CollectionViewBaseChrome key="chrome" + // docView={this.SelectedCollection} + // fieldKey={this.SelectedCollection.LayoutFieldKey} + // type={StrCast(this.SelectedCollection?.props.Document._viewType, CollectionViewType.Invalid) as CollectionViewType} />, + // prop, + // /*button*/]); } } @@ -720,7 +783,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })} style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001, fontSize: this._dotsize[i], padding: 0, textAlign: "center" }}> • - </button> + </button> </Tooltip>)} </div>; } @@ -991,7 +1054,7 @@ export class CollectionTreeViewChrome extends React.Component<CollectionMenuProp <button className="collectionTreeViewChrome-sort" onClick={this.toggleSort}> <div className="collectionTreeViewChrome-sortLabel"> Sort - </div> + </div> <div className="collectionTreeViewChrome-sortIcon" style={{ transform: `rotate(${this.ascending === undefined ? "90" : this.ascending ? "180" : "0"}deg)` }}> <FontAwesomeIcon icon="caret-up" size="2x" color="white" /> </div> @@ -1225,3 +1288,4 @@ Scripting.addGlobal(function gotoFrame(doc: any, newFrame: any) { CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0); doc._currentFrame = newFrame === undefined ? 0 : Math.max(0, newFrame); }); + diff --git a/src/client/views/collections/CollectionStackedTimeline.scss b/src/client/views/collections/CollectionStackedTimeline.scss index e456c0664..59c21210a 100644 --- a/src/client/views/collections/CollectionStackedTimeline.scss +++ b/src/client/views/collections/CollectionStackedTimeline.scss @@ -1,70 +1,94 @@ +@import "../global/globalCssVariables.scss"; + .collectionStackedTimeline { + position: absolute; + width: 100%; + height: 100%; + z-index: 1000; + overflow: hidden; + top: 0px; + + .collectionStackedTimeline-trim-shade { position: absolute; - width: 100%; height: 100%; - border: gray solid 1px; - border-radius: 3px; - z-index: 1000; - overflow: hidden; - top: 0px; + background-color: $dark-gray; + opacity: 0.3; + } - .collectionStackedTimeline-selector { - position: absolute; - width: 10px; - top: 2.5%; - height: 95%; - background: lightblue; - border-radius: 5px; - opacity: 0.3; - z-index: 500; - border-style: solid; - border-color: darkblue; - border-width: 1px; - } + .collectionStackedTimeline-trim-controls { + height: 100%; + position: absolute; + box-sizing: border-box; + border: 2px solid $medium-blue; + display: flex; + justify-content: space-between; + max-width: 100%; - .collectionStackedTimeline-current { - width: 1px; - height: 100%; - background-color: red; - position: absolute; - top: 0px; - pointer-events: none; + .collectionStackedTimeline-trim-handle { + background-color: $medium-blue; + height: 100%; + width: 5px; + cursor: ew-resize; } + } - .collectionStackedTimeline-marker-timeline { - position: absolute; - top: 2.5%; - height: 95%; - border-radius: 4px; - &:hover { - opacity: 1; - } + .collectionStackedTimeline-selector { + position: absolute; + width: 10px; + top: 2.5%; + height: 95%; + background: $light-blue; + border-radius: 3px; + opacity: 0.3; + z-index: 500; + border-style: solid; + border-color: $medium-blue; + border-width: 1px; + } - .collectionStackedTimeline-left-resizer, - .collectionStackedTimeline-resizer { - background: dimgrey; - position: absolute; - top: 0; - height: 100%; - width: 10px; - pointer-events: all; - cursor: ew-resize; - z-index: 100; - } - .collectionStackedTimeline-resizer { - right: 0; - } - .collectionStackedTimeline-left-resizer { - left: 0; - } + .collectionStackedTimeline-current { + width: 1px; + height: 100%; + background-color: $pink; + position: absolute; + top: 0px; + pointer-events: none; + } + + .collectionStackedTimeline-marker-timeline { + position: absolute; + top: 2.5%; + height: 95%; + border-radius: 4px; + &:hover { + opacity: 1; } - .collectionStackedTimeline-waveform { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - pointer-events: none; + .collectionStackedTimeline-left-resizer, + .collectionStackedTimeline-resizer { + background: $medium-gray; + position: absolute; + top: 0; + height: 100%; + width: 10px; + pointer-events: all; + cursor: ew-resize; + z-index: 100; + } + .collectionStackedTimeline-resizer { + right: 0; } -}
\ No newline at end of file + .collectionStackedTimeline-left-resizer { + left: 0; + } + } + + .collectionStackedTimeline-waveform { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + pointer-events: none; + } +} diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index a2c95df6e..d98d966d8 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -1,5 +1,12 @@ import React = require("react"); -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; +import { + action, + computed, + IReactionDisposer, + observable, + reaction, + runInAction, +} from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; import { Doc, DocListCast } from "../../../fields/Doc"; @@ -8,7 +15,16 @@ import { List } from "../../../fields/List"; import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField, ScriptField } from "../../../fields/ScriptField"; import { Cast, NumCast } from "../../../fields/Types"; -import { emptyFunction, formatTime, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, StopEvent, returnTrue } from "../../../Utils"; +import { + emptyFunction, + formatTime, + OmitKeys, + returnFalse, + returnOne, + setupMoveUpEvents, + StopEvent, + returnTrue, +} from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { LinkManager } from "../../util/LinkManager"; import { Scripting } from "../../util/Scripting"; @@ -18,9 +34,15 @@ import { undoBatch } from "../../util/UndoManager"; import { AudioWaveform } from "../AudioWaveform"; import { CollectionSubView } from "../collections/CollectionSubView"; import { LightboxView } from "../LightboxView"; -import { DocAfterFocusFunc, DocFocusFunc, DocumentView, DocumentViewProps } from "../nodes/DocumentView"; +import { + DocAfterFocusFunc, + DocFocusFunc, + DocumentView, + DocumentViewProps, +} from "../nodes/DocumentView"; import { LabelBox } from "../nodes/LabelBox"; import "./CollectionStackedTimeline.scss"; +import { Colors } from "../global/globalEnums"; type PanZoomDocument = makeInterface<[]>; const PanZoomDocument = makeInterface(); @@ -36,11 +58,21 @@ export type CollectionStackedTimelineProps = { endTag: string; mediaPath: string; dictationKey: string; + trimming: boolean; + trimStart: number; + trimEnd: number; + trimDuration: number; + setStartTrim: (newStart: number) => void; + setEndTrim: (newEnd: number) => void; }; @observer -export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument, CollectionStackedTimelineProps>(PanZoomDocument) { - @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined; +export class CollectionStackedTimeline extends CollectionSubView< + PanZoomDocument, + CollectionStackedTimelineProps +>(PanZoomDocument) { + @observable static SelectingRegion: CollectionStackedTimeline | undefined = + undefined; static RangeScript: ScriptField; static LabelScript: ScriptField; static RangePlayScript: ScriptField; @@ -50,48 +82,111 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument private _markerStart: number = 0; @observable _markerEnd: number = 0; - get duration() { return this.props.duration; } - @computed get currentTime() { return NumCast(this.layoutDoc._currentTimecode); } + get minLength() { + const rect = this._timeline?.getBoundingClientRect(); + if (rect) { + return 0.05 * this.duration; + } + return 0; + } + + get trimStart() { + return this.props.trimStart; + } + + get trimEnd() { + return this.props.trimEnd; + } + + get duration() { + return this.props.duration; + } + + @computed get currentTime() { + return NumCast(this.layoutDoc._currentTimecode); + } @computed get selectionContainer() { - return CollectionStackedTimeline.SelectingRegion !== this ? (null) : <div className="collectionStackedTimeline-selector" style={{ - left: `${Math.min(NumCast(this._markerStart), NumCast(this._markerEnd)) / this.duration * 100}%`, - width: `${Math.abs(this._markerStart - this._markerEnd) / this.duration * 100}%` - }} />; + return CollectionStackedTimeline.SelectingRegion !== this ? null : ( + <div + className="collectionStackedTimeline-selector" + style={{ + left: `${((Math.min(this._markerStart, this._markerEnd) - this.trimStart) / this.props.trimDuration) * 100}%`, + width: `${(Math.abs(this._markerStart - this._markerEnd) / this.props.trimDuration) * 100}%`, + }} + /> + ); } constructor(props: any) { super(props); // onClick play scripts - CollectionStackedTimeline.RangeScript = CollectionStackedTimeline.RangeScript || ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!; - CollectionStackedTimeline.RangePlayScript = CollectionStackedTimeline.RangePlayScript || ScriptField.MakeFunction(`scriptContext.playOnClick(this, clientX)`, { self: Doc.name, scriptContext: "any", clientX: "number" })!; + CollectionStackedTimeline.RangeScript = + CollectionStackedTimeline.RangeScript || + ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, { + self: Doc.name, + scriptContext: "any", + clientX: "number", + })!; + CollectionStackedTimeline.RangePlayScript = + CollectionStackedTimeline.RangePlayScript || + ScriptField.MakeFunction(`scriptContext.playOnClick(this, clientX)`, { + self: Doc.name, + scriptContext: "any", + clientX: "number", + })!; } - componentDidMount() { document.addEventListener("keydown", this.keyEvents, true); } + componentDidMount() { + document.addEventListener("keydown", this.keyEvents, true); + } componentWillUnmount() { document.removeEventListener("keydown", this.keyEvents, true); - if (CollectionStackedTimeline.SelectingRegion === this) runInAction(() => CollectionStackedTimeline.SelectingRegion = undefined); + if (CollectionStackedTimeline.SelectingRegion === this) { + runInAction( + () => (CollectionStackedTimeline.SelectingRegion = undefined) + ); + } } - anchorStart = (anchor: Doc) => NumCast(anchor._timecodeToShow, NumCast(anchor[this.props.startTag])); + anchorStart = (anchor: Doc) => + NumCast(anchor._timecodeToShow, NumCast(anchor[this.props.startTag])) anchorEnd = (anchor: Doc, val: any = null) => { const endVal = NumCast(anchor[this.props.endTag], val); - return NumCast(anchor._timecodeToHide, endVal === undefined ? null : endVal); + return NumCast( + anchor._timecodeToHide, + endVal === undefined ? null : endVal + ); } - toTimeline = (screen_delta: number, width: number) => Math.max(0, Math.min(this.duration, screen_delta / width * this.duration)); + toTimeline = (screen_delta: number, width: number) => { + return Math.max( + this.trimStart, + Math.min(this.trimEnd, (screen_delta / width) * this.props.trimDuration + this.trimStart)); + } + rangeClickScript = () => CollectionStackedTimeline.RangeScript; rangePlayScript = () => CollectionStackedTimeline.RangePlayScript; // for creating key anchors with key events @action keyEvents = (e: KeyboardEvent) => { - if (!(e.target instanceof HTMLInputElement) && this.props.isSelected(true)) { + if ( + !(e.target instanceof HTMLInputElement) && + this.props.isSelected(true) + ) { switch (e.key) { case " ": if (!CollectionStackedTimeline.SelectingRegion) { this._markerStart = this._markerEnd = this.currentTime; CollectionStackedTimeline.SelectingRegion = this; } else { - CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.props.fieldKey, this.props.startTag, this.props.endTag, this.currentTime); + CollectionStackedTimeline.createAnchor( + this.rootDoc, + this.dataDoc, + this.props.fieldKey, + this.props.startTag, + this.props.endTag, + this.currentTime + ); CollectionStackedTimeline.SelectingRegion = undefined; } } @@ -101,7 +196,10 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument getLinkData(l: Doc) { let la1 = l.anchor1 as Doc; let la2 = l.anchor2 as Doc; - const linkTime = NumCast(la2[this.props.startTag], NumCast(la1[this.props.startTag])); + const linkTime = NumCast( + la2[this.props.startTag], + NumCast(la1[this.props.startTag]) + ); if (Doc.AreProtosEqual(la1, this.dataDoc)) { la1 = l.anchor2 as Doc; la2 = l.anchor1 as Doc; @@ -118,10 +216,18 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument const wasPlaying = this.props.playing(); if (wasPlaying) this.props.Pause(); const wasSelecting = CollectionStackedTimeline.SelectingRegion === this; - setupMoveUpEvents(this, e, - action(e => { - if (!wasSelecting && CollectionStackedTimeline.SelectingRegion !== this) { - this._markerStart = this._markerEnd = this.toTimeline(clientX - rect.x, rect.width); + setupMoveUpEvents( + this, + e, + action((e) => { + if ( + !wasSelecting && + CollectionStackedTimeline.SelectingRegion !== this + ) { + this._markerStart = this._markerEnd = this.toTimeline( + clientX - rect.x, + rect.width + ); CollectionStackedTimeline.SelectingRegion = this; } this._markerEnd = this.toTimeline(e.clientX - rect.x, rect.width); @@ -134,32 +240,129 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument this._markerStart = this._markerEnd; this._markerEnd = tmp; } - if (!isClick && CollectionStackedTimeline.SelectingRegion === this && (Math.abs(movement[0]) > 15)) { - CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.props.fieldKey, this.props.startTag, this.props.endTag, - this._markerStart, this._markerEnd); + if ( + !isClick && + CollectionStackedTimeline.SelectingRegion === this && + Math.abs(movement[0]) > 15 && + !this.props.trimming + ) { + CollectionStackedTimeline.createAnchor( + this.rootDoc, + this.dataDoc, + this.props.fieldKey, + this.props.startTag, + this.props.endTag, + this._markerStart, + this._markerEnd + ); } - (!isClick || !wasSelecting) && (CollectionStackedTimeline.SelectingRegion = undefined); + (!isClick || !wasSelecting) && + (CollectionStackedTimeline.SelectingRegion = undefined); }), (e, doubleTap) => { this.props.select(false); - e.shiftKey && CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.props.fieldKey, this.props.startTag, this.props.endTag, this.currentTime); + e.shiftKey && + CollectionStackedTimeline.createAnchor( + this.rootDoc, + this.dataDoc, + this.props.fieldKey, + this.props.startTag, + this.props.endTag, + this.currentTime + ); !wasPlaying && doubleTap && this.props.Play(); }, - this.props.isSelected(true) || this.props.isContentActive(), undefined, - () => !wasPlaying && this.props.setTime((clientX - rect.x) / rect.width * this.duration)); + this.props.isSelected(true) || this.props.isContentActive(), + undefined, + () => { + !wasPlaying && + (this.props.trimming && this.duration ? + this.props.setTime(((clientX - rect.x) / rect.width) * this.duration) + : + this.props.setTime(((clientX - rect.x) / rect.width) * this.props.trimDuration + this.trimStart) + ); + } + ); } + + } + + @action + trimLeft = (e: React.PointerEvent): void => { + const rect = this._timeline?.getBoundingClientRect(); + const clientX = e.movementX; + setupMoveUpEvents( + this, + e, + action((e, [], []) => { + if (rect && this.props.isContentActive()) { + this.props.setStartTrim(Math.min( + Math.max( + this.trimStart + (e.movementX / rect.width) * this.duration, + 0 + ), + this.trimEnd - this.minLength + )); + } + return false; + }), + emptyFunction, + action((e, doubleTap) => { + if (doubleTap) { + this.props.setStartTrim(0); + } + }) + ); + } + + @action + trimRight = (e: React.PointerEvent): void => { + const rect = this._timeline?.getBoundingClientRect(); + const clientX = e.movementX; + setupMoveUpEvents( + this, + e, + action((e, [], []) => { + if (rect && this.props.isContentActive()) { + this.props.setEndTrim(Math.max( + Math.min( + this.trimEnd + (e.movementX / rect.width) * this.duration, + this.duration + ), + this.trimStart + this.minLength + )); + } + return false; + }), + emptyFunction, + action((e, doubleTap) => { + if (doubleTap) { + this.props.setEndTrim(this.duration); + } + }) + ); } @undoBatch @action - static createAnchor(rootDoc: Doc, dataDoc: Doc, fieldKey: string, startTag: string, endTag: string, anchorStartTime?: number, anchorEndTime?: number) { + static createAnchor( + rootDoc: Doc, + dataDoc: Doc, + fieldKey: string, + startTag: string, + endTag: string, + anchorStartTime?: number, + anchorEndTime?: number + ) { if (anchorStartTime === undefined) return rootDoc; const anchor = Docs.Create.LabelDocument({ - title: ComputedField.MakeFunction(`"#" + formatToTime(self["${startTag}"]) + "-" + formatToTime(self["${endTag}"])`) as any, + title: ComputedField.MakeFunction( + `"#" + formatToTime(self["${startTag}"]) + "-" + formatToTime(self["${endTag}"])` + ) as any, useLinkSmallAnchor: true, hideLinkButton: true, annotationOn: rootDoc, - _timelineLabel: true + _timelineLabel: true, }); Doc.GetProto(anchor)[startTag] = anchorStartTime; Doc.GetProto(anchor)[endTag] = anchorEndTime; @@ -179,7 +382,10 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument if (this.props.playing()) this.props.Pause(); else this.props.playFrom(seekTimeInSeconds, endTime); } else { - if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) && endTime > NumCast(this.layoutDoc._currentTimecode)) { + if ( + seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) && + endTime > NumCast(this.layoutDoc._currentTimecode) + ) { if (!this.layoutDoc.autoPlayAnchors && this.props.playing()) { this.props.Pause(); } else { @@ -194,39 +400,60 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument @action clickAnchor = (anchorDoc: Doc, clientX: number) => { - if (anchorDoc.isLinkButton) LinkManager.FollowLink(undefined, anchorDoc, this.props, false); + if (anchorDoc.isLinkButton) { + LinkManager.FollowLink(undefined, anchorDoc, this.props, false); + } const seekTimeInSeconds = this.anchorStart(anchorDoc) - 0.25; const endTime = this.anchorEnd(anchorDoc); - if (seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) + 1e-4 && endTime > NumCast(this.layoutDoc._currentTimecode) - 1e-4) { + if ( + seekTimeInSeconds < NumCast(this.layoutDoc._currentTimecode) + 1e-4 && + endTime > NumCast(this.layoutDoc._currentTimecode) - 1e-4 + ) { if (this.props.playing()) this.props.Pause(); else if (this.layoutDoc.autoPlayAnchors) this.props.Play(); else if (!this.layoutDoc.autoPlayAnchors) { const rect = this._timeline?.getBoundingClientRect(); - rect && this.props.setTime(this.toTimeline(clientX - rect.x, rect.width)); + rect && + this.props.setTime(this.toTimeline(clientX - rect.x, rect.width)); } } else { - if (this.layoutDoc.autoPlayAnchors) this.props.playFrom(seekTimeInSeconds, endTime); - else this.props.setTime(seekTimeInSeconds); + if (this.layoutDoc.autoPlayAnchors) { + this.props.playFrom(seekTimeInSeconds, endTime); + } + else { + this.props.setTime(seekTimeInSeconds); + } } return { select: true }; } - // makes sure no anchors overlaps each other by setting the correct position and width - getLevel = (m: Doc, placed: { anchorStartTime: number, anchorEndTime: number, level: number }[]) => { + getLevel = ( + m: Doc, + placed: { anchorStartTime: number; anchorEndTime: number; level: number }[] + ) => { const timelineContentWidth = this.props.PanelWidth(); const x1 = this.anchorStart(m); - const x2 = this.anchorEnd(m, x1 + 10 / timelineContentWidth * this.duration); + const x2 = this.anchorEnd( + m, + x1 + (10 / timelineContentWidth) * this.duration + ); let max = 0; - const overlappedLevels = new Set(placed.map(p => { - const y1 = p.anchorStartTime; - const y2 = p.anchorEndTime; - if ((x1 >= y1 && x1 <= y2) || (x2 >= y1 && x2 <= y2) || - (y1 >= x1 && y1 <= x2) || (y2 >= x1 && y2 <= x2)) { - max = Math.max(max, p.level); - return p.level; - } - })); + const overlappedLevels = new Set( + placed.map((p) => { + const y1 = p.anchorStartTime; + const y2 = p.anchorEndTime; + if ( + (x1 >= y1 && x1 <= y2) || + (x2 >= y1 && x2 <= y2) || + (y1 >= x1 && y1 <= x2) || + (y2 >= x1 && y2 <= x2) + ) { + max = Math.max(max, p.level); + return p.level; + } + }) + ); let level = max + 1; for (let j = max; j >= 0; j--) !overlappedLevels.has(j) && (level = j); @@ -235,82 +462,185 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument } dictationHeightPercent = 50; - dictationHeight = () => this.props.PanelHeight() * (100 - this.dictationHeightPercent) / 100; - timelineContentHeight = () => this.props.PanelHeight() * this.dictationHeightPercent / 100; - dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight()); + dictationHeight = () => + (this.props.PanelHeight() * (100 - this.dictationHeightPercent)) / 100 + timelineContentHeight = () => + (this.props.PanelHeight() * this.dictationHeightPercent) / 100 + dictationScreenToLocalTransform = () => + this.props + .ScreenToLocalTransform() + .translate(0, -this.timelineContentHeight()) @computed get renderDictation() { const dictation = Cast(this.dataDoc[this.props.dictationKey], Doc, null); - return !dictation ? (null) : <div style={{ position: "absolute", height: "100%", top: this.timelineContentHeight(), background: "tan" }}> - <DocumentView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} - Document={dictation} - PanelHeight={this.dictationHeight} - isAnnotationOverlay={true} - isDocumentActive={returnFalse} - select={emptyFunction} - scaling={returnOne} - xMargin={25} - yMargin={10} - ScreenToLocalTransform={this.dictationScreenToLocalTransform} - whenChildContentsActiveChanged={emptyFunction} - removeDocument={returnFalse} - moveDocument={returnFalse} - addDocument={returnFalse} - CollectionView={undefined} - renderDepth={this.props.renderDepth + 1}> - </DocumentView> - </div>; + return !dictation ? null : ( + <div + style={{ + position: "absolute", + height: "100%", + top: this.timelineContentHeight(), + background: Colors.LIGHT_BLUE, + }} + > + <DocumentView + {...OmitKeys(this.props, [ + "NativeWidth", + "NativeHeight", + "setContentView", + ]).omit} + Document={dictation} + PanelHeight={this.dictationHeight} + isAnnotationOverlay={true} + isDocumentActive={returnFalse} + select={emptyFunction} + scaling={returnOne} + xMargin={25} + yMargin={10} + ScreenToLocalTransform={this.dictationScreenToLocalTransform} + whenChildContentsActiveChanged={emptyFunction} + removeDocument={returnFalse} + moveDocument={returnFalse} + addDocument={returnFalse} + CollectionView={undefined} + renderDepth={this.props.renderDepth + 1} + ></DocumentView> + </div> + ); } @computed get renderAudioWaveform() { - return !this.props.mediaPath ? (null) : - <div className="collectionStackedTimeline-waveform" > + return !this.props.mediaPath ? null : ( + <div className="collectionStackedTimeline-waveform"> <AudioWaveform duration={this.duration} mediaPath={this.props.mediaPath} - dataDoc={this.dataDoc} - PanelHeight={this.timelineContentHeight} /> - </div>; + layoutDoc={this.layoutDoc} + PanelHeight={this.timelineContentHeight} + trimming={this.props.trimming} + /> + </div> + ); } + currentTimecode = () => this.currentTime; render() { const timelineContentWidth = this.props.PanelWidth(); - const overlaps: { anchorStartTime: number, anchorEndTime: number, level: number }[] = []; - const drawAnchors = this.childDocs.map(anchor => ({ level: this.getLevel(anchor, overlaps), anchor })); + const overlaps: { + anchorStartTime: number; + anchorEndTime: number; + level: number; + }[] = []; + const drawAnchors = this.childDocs.map((anchor) => ({ + level: this.getLevel(anchor, overlaps), + anchor, + })); const maxLevel = overlaps.reduce((m, o) => Math.max(m, o.level), 0) + 2; - const isActive = this.props.isContentActive() || this.props.isSelected(false); - return <div className="collectionStackedTimeline" ref={(timeline: HTMLDivElement | null) => this._timeline = timeline} - onClick={e => isActive && StopEvent(e)} onPointerDown={e => isActive && this.onPointerDownTimeline(e)}> - {drawAnchors.map(d => { - const start = this.anchorStart(d.anchor); - const end = this.anchorEnd(d.anchor, start + 10 / timelineContentWidth * this.duration); - const left = start / this.duration * timelineContentWidth; - const top = d.level / maxLevel * this.timelineContentHeight(); - const timespan = end - start; - return this.props.Document.hideAnchors ? (null) : - <div className={"collectionStackedTimeline-marker-timeline"} key={d.anchor[Id]} - style={{ left, top, width: `${timespan / this.duration * timelineContentWidth}px`, height: `${this.timelineContentHeight() / maxLevel}px` }} - onClick={e => { this.props.playFrom(start, this.anchorEnd(d.anchor)); e.stopPropagation(); }} > - <StackedTimelineAnchor {...this.props} - mark={d.anchor} - rangeClickScript={this.rangeClickScript} - rangePlayScript={this.rangePlayScript} - left={left} - top={top} - width={timelineContentWidth * timespan / this.duration} - height={this.timelineContentHeight() / maxLevel} - toTimeline={this.toTimeline} - layoutDoc={this.layoutDoc} - currentTimecode={this.currentTimecode} - _timeline={this._timeline} - stackedTimeline={this} - /> - </div>; - })} - {this.selectionContainer} - {this.renderAudioWaveform} - {this.renderDictation} - - <div className="collectionStackedTimeline-current" style={{ left: `${this.currentTime / this.duration * 100}%` }} /> - </div>; + const isActive = + this.props.isContentActive() || this.props.isSelected(false); + return ( + <div + className="collectionStackedTimeline" + ref={(timeline: HTMLDivElement | null) => (this._timeline = timeline)} + onClick={(e) => isActive && StopEvent(e)} + onPointerDown={(e) => isActive && this.onPointerDownTimeline(e)} + > + {drawAnchors.map((d) => { + + const start = this.anchorStart(d.anchor); + const end = this.anchorEnd( + d.anchor, + start + (10 / timelineContentWidth) * this.duration + ); + const left = this.props.trimming ? + (start / this.duration) * timelineContentWidth + : (start - this.trimStart) / this.props.trimDuration * timelineContentWidth; + const top = (d.level / maxLevel) * this.timelineContentHeight(); + const timespan = end - start; + const width = (timespan / this.props.trimDuration) * timelineContentWidth; + const height = this.timelineContentHeight() / maxLevel; + return this.props.Document.hideAnchors ? null : ( + <div + className={"collectionStackedTimeline-marker-timeline"} + key={d.anchor[Id]} + style={{ + left, + top, + width: `${width}px`, + height: `${height}px`, + }} + onClick={(e) => { + this.props.playFrom(start, this.anchorEnd(d.anchor)); + e.stopPropagation(); + }} + > + <StackedTimelineAnchor + {...this.props} + mark={d.anchor} + rangeClickScript={this.rangeClickScript} + rangePlayScript={this.rangePlayScript} + left={left} + top={top} + width={width} + height={height} + toTimeline={this.toTimeline} + layoutDoc={this.layoutDoc} + currentTimecode={this.currentTimecode} + _timeline={this._timeline} + stackedTimeline={this} + trimStart={this.trimStart} + trimEnd={this.trimEnd} + /> + </div> + ); + })} + {!this.props.trimming && this.selectionContainer} + {this.renderAudioWaveform} + {this.renderDictation} + + <div + className="collectionStackedTimeline-current" + style={{ + left: this.props.trimming + ? `${(this.currentTime / this.duration) * 100}%` + : `${(this.currentTime - this.trimStart) / (this.trimEnd - this.trimStart) * 100}%`, + }} + /> + + {this.props.trimming && ( + <> + <div + className="collectionStackedTimeline-trim-shade" + style={{ width: `${(this.trimStart / this.duration) * 100}%` }} + ></div> + + <div + className="collectionStackedTimeline-trim-controls" + style={{ + left: `${(this.trimStart / this.duration) * 100}%`, + width: `${((this.trimEnd - this.trimStart) / this.duration) * 100 + }%`, + }} + > + <div + className="collectionStackedTimeline-trim-handle" + onPointerDown={this.trimLeft} + ></div> + <div + className="collectionStackedTimeline-trim-handle" + onPointerDown={this.trimRight} + ></div> + </div> + + <div + className="collectionStackedTimeline-trim-shade" + style={{ + left: `${(this.trimEnd / this.duration) * 100}%`, + width: `${((this.duration - this.trimEnd) / this.duration) * 100 + }%`, + }} + ></div> + </> + )} + </div> + ); } } @@ -335,6 +665,8 @@ interface StackedTimelineAnchorProps { currentTimecode: () => number; isSelected: (outsideReaction?: boolean) => boolean; stackedTimeline: CollectionStackedTimeline; + trimStart: number; + trimEnd: number; } @observer class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps> { @@ -345,22 +677,41 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps> this._lastTimecode = this.props.currentTimecode(); } componentDidMount() { - this._disposer = reaction(() => this.props.currentTimecode(), + this._disposer = reaction( + () => this.props.currentTimecode(), (time) => { - const dictationDoc = Cast(this.props.layoutDoc["data-dictation"], Doc, null); - const isDictation = dictationDoc && DocListCast(this.props.mark.links).some(link => Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc); - if (!LightboxView.LightboxDoc + const dictationDoc = Cast( + this.props.layoutDoc["data-dictation"], + Doc, + null + ); + const isDictation = + dictationDoc && + DocListCast(this.props.mark.links).some( + (link) => + Cast(link.anchor1, Doc, null)?.annotationOn === dictationDoc + ); + if ( + !LightboxView.LightboxDoc && // bcz: when should links be followed? we don't want to move away from the video to follow a link but we can open it in a sidebar/etc. But we don't know that upfront. // for now, we won't follow any links when the lightbox is oepn to avoid "losing" the video. /*(isDictation || !Doc.AreProtosEqual(LightboxView.LightboxDoc, this.props.layoutDoc))*/ - && DocListCast(this.props.mark.links).length && + DocListCast(this.props.mark.links).length && time > NumCast(this.props.mark[this.props.startTag]) && time < NumCast(this.props.mark[this.props.endTag]) && - this._lastTimecode < NumCast(this.props.mark[this.props.startTag])) { - LinkManager.FollowLink(undefined, this.props.mark, this.props as any as DocumentViewProps, false, true); + this._lastTimecode < NumCast(this.props.mark[this.props.startTag]) + ) { + LinkManager.FollowLink( + undefined, + this.props.mark, + this.props as any as DocumentViewProps, + false, + true + ); } this._lastTimecode = time; - }); + } + ); } componentWillUnmount() { this._disposer?.(); @@ -373,57 +724,136 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps> return this.props.toTimeline(e.clientX - rect.x, rect.width); }; const changeAnchor = (anchor: Doc, left: boolean, time: number) => { - const timelineOnly = Cast(anchor[this.props.startTag], "number", null) !== undefined; - if (timelineOnly) Doc.SetInPlace(anchor, left ? this.props.startTag : this.props.endTag, time, true); - else left ? anchor._timecodeToShow = time : anchor._timecodeToHide = time; + const timelineOnly = + Cast(anchor[this.props.startTag], "number", null) !== undefined; + if (timelineOnly) { + Doc.SetInPlace( + anchor, + left ? this.props.startTag : this.props.endTag, + time, + true + ); + } + else { + left + ? (anchor._timecodeToShow = time) + : (anchor._timecodeToHide = time); + } return false; }; - setupMoveUpEvents(this, e, + setupMoveUpEvents( + this, + e, (e) => changeAnchor(anchor, left, newTime(e)), (e) => { this.props.setTime(newTime(e)); this.props._timeline?.releasePointerCapture(e.pointerId); }, - emptyFunction); + emptyFunction + ); } - renderInner = computedFn(function (this: StackedTimelineAnchor, mark: Doc, script: undefined | (() => ScriptField), doublescript: undefined | (() => ScriptField), x: number, y: number, width: number, height: number) { + + @action + computeTitle = () => { + const start = Math.max(NumCast(this.props.mark[this.props.startTag]), this.props.trimStart) - this.props.trimStart; + const end = Math.min(NumCast(this.props.mark[this.props.endTag]), this.props.trimEnd) - this.props.trimStart; + return `#${formatTime(start)}-${formatTime(end)}`; + } + + renderInner = computedFn(function ( + this: StackedTimelineAnchor, + mark: Doc, + script: undefined | (() => ScriptField), + doublescript: undefined | (() => ScriptField), + x: number, + y: number, + width: number, + height: number + ) { const anchor = observable({ view: undefined as any }); - const focusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, docTransform?: Transform) => { + const focusFunc = ( + doc: Doc, + willZoom?: boolean, + scale?: number, + afterFocus?: DocAfterFocusFunc, + docTransform?: Transform + ) => { this.props.playLink(mark); this.props.focus(doc, { willZoom, scale, afterFocus, docTransform }); }; return { - anchor, view: <DocumentView key="view" {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} - ref={action((r: DocumentView | null) => anchor.view = r)} - Document={mark} - DataDoc={undefined} - renderDepth={this.props.renderDepth + 1} - LayoutTemplate={undefined} - LayoutTemplateString={LabelBox.LayoutString("data")} - isDocumentActive={returnFalse} - PanelWidth={() => width} - PanelHeight={() => height} - ScreenToLocalTransform={() => this.props.ScreenToLocalTransform().translate(-x, -y)} - focus={focusFunc} - rootSelected={returnFalse} - onClick={script} - onDoubleClick={this.props.layoutDoc.autoPlayAnchors ? undefined : doublescript} - ignoreAutoHeight={false} - hideResizeHandles={true} - bringToFront={emptyFunction} - scriptContext={this.props.stackedTimeline} /> + anchor, + view: ( + <DocumentView + key="view" + {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} + ref={action((r: DocumentView | null) => (anchor.view = r))} + Document={mark} + DataDoc={undefined} + renderDepth={this.props.renderDepth + 1} + LayoutTemplate={undefined} + LayoutTemplateString={LabelBox.LayoutStringWithTitle(LabelBox, "data", this.computeTitle())} + isDocumentActive={returnFalse} + PanelWidth={() => width} + PanelHeight={() => height} + ScreenToLocalTransform={() => + this.props.ScreenToLocalTransform().translate(-x, -y) + } + focus={focusFunc} + rootSelected={returnFalse} + onClick={script} + onDoubleClick={ + this.props.layoutDoc.autoPlayAnchors ? undefined : doublescript + } + ignoreAutoHeight={false} + hideResizeHandles={true} + bringToFront={emptyFunction} + scriptContext={this.props.stackedTimeline} + /> + ), }; }); + render() { - const inner = this.renderInner(this.props.mark, this.props.rangeClickScript, this.props.rangePlayScript, this.props.left, this.props.top, this.props.width, this.props.height); - return <> - {inner.view} - {!inner.anchor.view || !SelectionManager.IsSelected(inner.anchor.view) ? (null) : - <> - <div key="left" className="collectionStackedTimeline-left-resizer" onPointerDown={e => this.onAnchorDown(e, this.props.mark, true)} /> - <div key="right" className="collectionStackedTimeline-resizer" onPointerDown={e => this.onAnchorDown(e, this.props.mark, false)} /> - </>} - </>; + const inner = this.renderInner( + this.props.mark, + this.props.rangeClickScript, + this.props.rangePlayScript, + this.props.left, + this.props.top, + this.props.width, + this.props.height + ); + return ( + <> + {inner.view} + {!inner.anchor.view || + !SelectionManager.IsSelected(inner.anchor.view) ? null : ( + <> + <div + key="left" + className="collectionStackedTimeline-left-resizer" + onPointerDown={(e) => this.onAnchorDown(e, this.props.mark, true)} + /> + <div + key="right" + className="collectionStackedTimeline-resizer" + onPointerDown={(e) => + this.onAnchorDown(e, this.props.mark, false) + } + /> + </> + )} + </> + ); } } -Scripting.addGlobal(function formatToTime(time: number): any { return formatTime(time); });
\ No newline at end of file +Scripting.addGlobal(function formatToTime(time: number): any { + return formatTime(time); +}); +Scripting.addGlobal(function min(num1: number, num2: number): number { + return Math.min(num1, num2); +}); +Scripting.addGlobal(function max(num1: number, num2: number): number { + return Math.max(num1, num2); +});
\ No newline at end of file diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss index a963f1cb9..7f62ecaa0 100644 --- a/src/client/views/collections/TabDocView.scss +++ b/src/client/views/collections/TabDocView.scss @@ -1,3 +1,6 @@ +@import "../global/globalCssVariables.scss"; + + input.lm_title:focus, input.lm_title { max-width: unset !important; @@ -57,12 +60,11 @@ input.lm_title { } } -.miniMap-hidden, .miniMap { position: absolute; overflow: hidden; - right: 10; - bottom: 10; + right: 15; + bottom: 15; border: solid 1px; box-shadow: black 0.4vw 0.4vw 0.8vw; width: 100%; @@ -82,17 +84,21 @@ input.lm_title { } .miniMap-hidden { + cursor: pointer; position: absolute; - bottom: 0; - right: 0; - width: 45px; - height: 45px; - transform: translate(20px, 20px) rotate(45deg); - border-radius: 30px; + bottom: 5; + display: flex; + right: 5; + width: 25px; + height: 25px; + border-radius: 3px; padding: 2px; + justify-content: center; + align-items: center; + align-content: center; + background-color: $light-gray; - >svg { - margin-top: 3px; - transform: translate(0px, 7px); + &:hover { + box-shadow: none; } }
\ No newline at end of file diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 117dba4de..28b074d35 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -33,6 +33,7 @@ import { CollectionView, CollectionViewType } from './CollectionView'; import "./TabDocView.scss"; import React = require("react"); import Color = require('color'); +import { Colors, Shadows } from '../global/globalEnums'; const _global = (window /* browser */ || global /* node */) as any; interface TabDocViewProps { @@ -123,6 +124,8 @@ export class TabDocView extends React.Component<TabDocViewProps> { tab.element[0].prepend(iconWrap); tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }), ({ layer, color }) => { + // console.log("TabDocView: " + this.tabColor); + // console.log("lightOrDark: " + lightOrDark(this.tabColor)); const textColor = lightOrDark(this.tabColor); //not working with StyleProp.Color titleEle.style.color = textColor; titleEle.style.backgroundColor = "transparent"; @@ -390,8 +393,15 @@ export class TabDocView extends React.Component<TabDocViewProps> { background={this.miniMapColor} document={this._document} tabView={this.tabView} /> - <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{"toggle minimap"}</div>}> - <div className="miniMap-hidden" onPointerDown={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} > + <Tooltip style={{ display: this.disableMinimap() ? "none" : undefined }} key="ttip" title={<div className="dash-tooltip">{this._document.hideMinimap ? "Open minimap" : "Close minimap"}</div>}> + <div className="miniMap-hidden" + style={{ + color: this._document.hideMinimap ? Colors.BLACK : Colors.WHITE, + backgroundColor: this._document.hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE, + boxShadow: this._document.hideMinimap ? Shadows.STANDARD_SHADOW : undefined + }} + onPointerDown={e => e.stopPropagation()} + onClick={action(e => { e.stopPropagation(); this._document!.hideMinimap = !this._document!.hideMinimap; })} > <FontAwesomeIcon icon={"globe-asia"} size="lg" /> </div> </Tooltip> diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index fb949a36d..1c54467c5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -510,7 +510,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P const points = ge.points; const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height); const inkDoc = Docs.Create.InkDocument(ActiveInkColor(), CurrentUserUtils.SelectedTool, ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), points, - { title: "ink stroke", x: B.x - Number(ActiveInkWidth()) / 2, y: B.y - Number(ActiveInkWidth()) / 2, _width: B.width + Number(ActiveInkWidth()), _height: B.height + Number(ActiveInkWidth()) }); + { title: "ink stroke", x: B.x - ActiveInkWidth() / 2, y: B.y - ActiveInkWidth() / 2, _width: B.width + ActiveInkWidth(), _height: B.height + ActiveInkWidth() }); this.addDocument(inkDoc); e.stopPropagation(); break; diff --git a/src/client/views/collections/collectionFreeForm/index.ts b/src/client/views/collections/collectionFreeForm/index.ts new file mode 100644 index 000000000..702dc8d42 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/index.ts @@ -0,0 +1,7 @@ +export * from "./CollectionFreeFormLayoutEngines"; +export * from "./CollectionFreeFormLinkView"; +export * from "./CollectionFreeFormLinksView"; +export * from "./CollectionFreeFormRemoteCursors"; +export * from "./CollectionFreeFormView"; +export * from "./MarqueeOptionsMenu"; +export * from "./MarqueeView";
\ No newline at end of file diff --git a/src/client/views/collections/collectionGrid/index.ts b/src/client/views/collections/collectionGrid/index.ts new file mode 100644 index 000000000..be5d5667a --- /dev/null +++ b/src/client/views/collections/collectionGrid/index.ts @@ -0,0 +1,2 @@ +export * from "./Grid"; +export * from "./CollectionGridView";
\ No newline at end of file diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss index 46e40489b..f249eb1f5 100644 --- a/src/client/views/collections/CollectionLinearView.scss +++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.scss @@ -1,15 +1,31 @@ -@import "../global/globalCssVariables"; -@import "../_nodeModuleOverrides"; +@import "../../global/globalCssVariables"; +@import "../../_nodeModuleOverrides"; .collectionLinearView-outer { overflow: visible; height: 100%; pointer-events: none; + &.true { + padding-left: 5px; + padding-right: 5px; + border-left: $standard-border; + background-color: $medium-blue-alt; + } + + >input:not(:checked)~&.true { + background-color: transparent; + } + .collectionLinearView { display: flex; height: 100%; align-items: center; + gap: 5px; + + .collectionView { + overflow: visible !important; + } >span { background: $dark-gray; @@ -41,7 +57,7 @@ } .bottomPopup-descriptions { - cursor:pointer; + cursor: pointer; display: inline; white-space: nowrap; padding-left: 8px; @@ -54,7 +70,7 @@ } .bottomPopup-exit { - cursor:pointer; + cursor: pointer; display: inline; white-space: nowrap; margin-right: 10px; @@ -67,29 +83,22 @@ } >label { - margin-top: "auto"; - margin-bottom: "auto"; - background: $dark-gray; - color: $white; - display: inline-block; - border-radius: 18px; - font-size: 12.5px; - width: 18px; - height: 18px; - margin-top: auto; - margin-bottom: auto; - margin-right: 3px; + pointer-events: all; cursor: pointer; + background-color: $medium-blue; + padding: 5; + border-radius: 2px; + height: 25; + min-width: 25; + margin: 0; + color: $white; + display: flex; + font-weight: 100; + width: fit-content; transition: transform 0.2s; - } - - label p { - padding-left: 5px; - } - - label:hover { - background: $medium-gray; - transform: scale(1.15); + align-items: center; + justify-content: center; + transition: 0.15s; } >input { @@ -110,13 +119,11 @@ display: flex; opacity: 1; position: relative; - margin-top: auto; .collectionLinearView-docBtn, .collectionLinearView-docBtn-scalable { position: relative; margin: auto; - margin-left: 3px; transform-origin: center 80%; } diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/collectionLinearView/CollectionLinearView.tsx index 52c836556..74d581946 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinearView/CollectionLinearView.tsx @@ -2,21 +2,22 @@ import { Tooltip } from '@material-ui/core'; import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, HeightSym, WidthSym } from '../../../fields/Doc'; -import { documentSchema } from '../../../fields/documentSchemas'; -import { Id } from '../../../fields/FieldSymbols'; -import { makeInterface } from '../../../fields/Schema'; -import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, Utils } from '../../../Utils'; -import { DragManager } from '../../util/DragManager'; -import { Transform } from '../../util/Transform'; -import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; -import { DocumentView } from '../nodes/DocumentView'; -import { LinkDescriptionPopup } from '../nodes/LinkDescriptionPopup'; -import { StyleProp } from '../StyleProvider'; +import { Doc, HeightSym, WidthSym } from '../../../../fields/Doc'; +import { documentSchema } from '../../../../fields/documentSchemas'; +import { Id } from '../../../../fields/FieldSymbols'; +import { makeInterface } from '../../../../fields/Schema'; +import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; +import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, Utils } from '../../../../Utils'; +import { DragManager } from '../../../util/DragManager'; +import { Transform } from '../../../util/Transform'; +import { DocumentLinksButton } from '../../nodes/DocumentLinksButton'; +import { DocumentView } from '../../nodes/DocumentView'; +import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup'; +import { StyleProp } from '../../StyleProvider'; import "./CollectionLinearView.scss"; -import { CollectionSubView } from './CollectionSubView'; -import { CollectionViewType } from './CollectionView'; +import { CollectionSubView } from '.././CollectionSubView'; +import { CollectionViewType } from '.././CollectionView'; +import { Colors, Shadows } from '../../global/globalEnums'; type LinearDocument = makeInterface<[typeof documentSchema,]>; @@ -107,35 +108,56 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { } render() { - const guid = Utils.GenerateGuid(); - const flexDir: any = StrCast(this.Document.flexDirection); + const guid = Utils.GenerateGuid(); // Generate a unique ID to use as the label + const flexDir: any = StrCast(this.Document.flexDirection); // Specify direction of linear view content + const flexGap: number = NumCast(this.Document.flexGap); // Specify the gap between linear view content + const expandable: boolean = BoolCast(this.props.Document.linearViewExpandable); // Specify whether it is expandable or not + const floating: boolean = BoolCast(this.props.Document.linearViewFloating); // Specify whether it is expandable or not + const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); - - const menuOpener = <label htmlFor={`${guid}`} style={{ pointerEvents: "all", cursor: "pointer", background: backgroundColor === color ? "black" : backgroundColor, }} + const icon: string = StrCast(this.props.Document.icon); // Menu opener toggle + const menuOpener = <label htmlFor={`${guid}`} + style={{ + color: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.BLACK, + backgroundColor: backgroundColor === color ? "black" : BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : Colors.LIGHT_GRAY + }} onPointerDown={e => e.stopPropagation()} > - <p>{BoolCast(this.layoutDoc.linearViewIsExpanded) ? "–" : "+"}</p> + <div className="collectionLinearView-menuOpener" + style={{ boxShadow: floating ? Shadows.STANDARD_SHADOW : undefined }} + > + {BoolCast(this.layoutDoc.linearViewIsExpanded) ? icon ? icon : "–" : icon ? icon : "+"} + </div> </label>; - return <div className="collectionLinearView-outer"> + return <div className={`collectionLinearView-outer ${this.layoutDoc.linearViewSubMenu}`} style={{ backgroundColor: BoolCast(this.layoutDoc.linearViewIsExpanded) ? undefined : "transparent" }}> <div className="collectionLinearView" ref={this.createDashEventsTarget} > - <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.layoutDoc.linearViewIsExpanded) ? "Close menu" : "Open menu"}</div></>} placement="top"> + {!expandable ? (null) : <Tooltip title={<><div className="dash-tooltip">{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close" : "Open"}</div></>} placement="top"> {menuOpener} - </Tooltip> - <input id={`${guid}`} type="checkbox" checked={BoolCast(this.layoutDoc.linearViewIsExpanded)} ref={this.addMenuToggle} - onChange={action(() => this.layoutDoc.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> - - <div className="collectionLinearView-content" style={{ height: this.dimension(), flexDirection: flexDir }}> + </Tooltip>} + <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.linearViewIsExpanded)} ref={this.addMenuToggle} + onChange={action(() => this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> + + <div className="collectionLinearView-content" + style={{ + height: this.dimension(), + flexDirection: flexDir, + gap: flexGap + }}> {this.childLayoutPairs.map((pair, ind) => { const nested = pair.layout._viewType === CollectionViewType.Linear; const dref = React.createRef<HTMLDivElement>(); - const scalable = pair.layout.onClick || pair.layout.onDragStart; - return <div className={`collectionLinearView-docBtn` + (scalable ? "-scalable" : "")} key={pair.layout[Id]} ref={dref} + const hidden = pair.layout.hidden === true; + // const scalable = pair.layout.onClick || pair.layout.onDragStart; + return hidden ? (null) : <div className={`collectionLinearView-docBtn`} key={pair.layout[Id]} ref={dref} style={{ pointerEvents: "all", - minWidth: 30, - width: nested ? pair.layout[WidthSym]() : this.dimension(), - height: nested && pair.layout.linearViewIsExpanded ? pair.layout[HeightSym]() : this.dimension(), + width: nested ? undefined : NumCast(pair.layout._width), + height: nested ? undefined : NumCast(pair.layout._height), + marginLeft: !nested ? 2.5 : 0, + marginRight: !nested ? 2.5 : 0, + // width: NumCast(pair.layout._width), + // height: NumCast(pair.layout._height), }} > <DocumentView Document={pair.layout} @@ -166,7 +188,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { </div>; })} </div> - {DocumentLinksButton.StartLink ? <span className="bottomPopup-background" style={{ + {DocumentLinksButton.StartLink && StrCast(this.layoutDoc.title) === "docked buttons" ? <span className="bottomPopup-background" style={{ pointerEvents: "all" }} onPointerDown={e => e.stopPropagation()} > diff --git a/src/client/views/collections/collectionLinearView/index.ts b/src/client/views/collections/collectionLinearView/index.ts new file mode 100644 index 000000000..ff73e14ae --- /dev/null +++ b/src/client/views/collections/collectionLinearView/index.ts @@ -0,0 +1 @@ +export * from "./CollectionLinearView";
\ No newline at end of file diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx index aaa50ba67..b28c32e0e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx @@ -413,7 +413,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> { bool = fields ? fields[1] === "check" : false; } return <div key={key} className="key-option" style={{ - border: "1px solid lightgray", paddingLeft: 5, textAlign: "left", + paddingLeft: 5, textAlign: "left", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white", }} > @@ -489,8 +489,10 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> { } render() { return ( - <div style={{ display: "flex" }} ref={this.setNode}> - <FontAwesomeIcon onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }} icon={this.props.icon} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} /> + <div style={{ display: "flex", width: '100%', alignContent: 'center', alignItems: 'center' }} ref={this.setNode}> + <div className="schema-icon" onClick={e => { this.props.openHeader(this.props.col, e.clientX, e.clientY); e.stopPropagation(); }}> + <FontAwesomeIcon icon={this.props.icon} size="lg" style={{ display: "inline" }} /> + </div> {/* <FontAwesomeIcon icon={fa.faSearchMinus} size="lg" style={{ display: "inline", paddingBottom: "1px", paddingTop: "4px", cursor: "hand" }} onClick={e => { runInAction(() => { this._isOpen === undefined ? this._isOpen = true : this._isOpen = !this._isOpen }) diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx index f48906ba5..0e19ef3d9 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaMovableRow.tsx @@ -134,9 +134,9 @@ export class MovableRow extends React.Component<MovableRowProps> { <div className="collectionSchema-row-wrapper" onKeyPress={this.onKeyDown} ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> <ReactTableDefaults.TrComponent onKeyPress={this.onKeyDown} > <div className="row-dragger"> - <div className="row-option" style={{ left: 5 }} onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div> - <div className="row-option" style={{ cursor: "grab", left: 25 }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div> - <div className="row-option" style={{ left: 40 }} onClick={() => this.props.addDocTab(this.props.rowInfo.original, "add:right")}><FontAwesomeIcon icon="external-link-alt" size="sm" /></div> + <div className="row-option" onClick={undoBatch(() => this.props.removeDoc(this.props.rowInfo.original))}><FontAwesomeIcon icon="trash" size="sm" /></div> + <div className="row-option" style={{ cursor: "grab" }} ref={reference} onPointerDown={onItemDown}><FontAwesomeIcon icon="grip-vertical" size="sm" /></div> + <div className="row-option" onClick={() => this.props.addDocTab(this.props.rowInfo.original, "add:right")}><FontAwesomeIcon icon="external-link-alt" size="sm" /></div> </div> {children} </ReactTableDefaults.TrComponent> diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss index 40cdcd14b..3074ce66e 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaView.scss +++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.scss @@ -108,9 +108,7 @@ } .rt-th { padding: 0; - border: solid lightgray; - border-width: 0 1px; - border-bottom: 2px solid lightgray; + border-left: solid 1px $light-gray; } } .rt-th { @@ -213,6 +211,8 @@ } } + + .collectionSchemaView-header { height: 100%; color: gray; @@ -227,6 +227,15 @@ button.add-column { width: 28px; } +.collectionSchemaView-menuOptions-wrapper { + background: rgb(241, 239, 235); + display: flex; + cursor: default; + height: 100%; + align-content: center; + align-items: center; +} + .collectionSchema-header-menuOptions { color: black; width: 180px; @@ -272,6 +281,9 @@ button.add-column { width: 10px; } } + + + .keys-dropdown { position: relative; //width: 100%; @@ -287,26 +299,7 @@ button.add-column { font-weight: normal; } } - .keys-options-wrapper { - width: 100%; - max-height: 150px; - overflow-y: scroll; - position: absolute; - top: 28px; - box-shadow: 0 10px 16px rgba(0, 0, 0, 0.1); - background-color: white; - .key-option { - background-color: white; - border: 1px solid lightgray; - padding: 2px 3px; - &:not(:first-child) { - border-top: 0; - } - &:hover { - background-color: $light-gray; - } - } - } + } .columnMenu-colors { display: flex; @@ -325,11 +318,53 @@ button.add-column { } } +.schema-icon { + cursor: pointer; + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + align-content: center; + background-color: $medium-blue; + color: white; + margin-right: 5px; + font-size: 10px; + border-radius: 3px; + +} + +.keys-options-wrapper { + position: absolute; + text-align: left; + height: fit-content; + top: 100%; + z-index: 21; + background-color: #ffffff; + box-shadow: 0px 3px 4px rgba(0,0,0,30%); + padding: 1px; + .key-option { + cursor: pointer; + color: #000000; + width: 100%; + height: 25px; + font-weight: 400; + display: flex; + justify-content: left; + align-items: center; + padding-left: 5px; + &:hover { + background-color: $light-gray; + } + } +} + .collectionSchema-row { height: 100%; background-color: white; &.row-focused .rt-td { - background-color: #bfffc0; //$light-gray; + background-color: $light-blue; //$light-gray; + overflow: visible; } &.row-wrapped { .rt-td { @@ -338,39 +373,40 @@ button.add-column { } .row-dragger { display: flex; - justify-content: space-around; - //flex: 50 0 auto; - width: 0; - max-width: 50px; - //height: 100%; + justify-content: space-evenly; + width: 58px; + position: absolute; + /* max-width: 50px; */ min-height: 30px; align-items: center; color: lightgray; background-color: white; transition: color 0.1s ease; .row-option { - // padding: 5px; + color: black; cursor: pointer; - position: absolute; + position: relative; transition: color 0.1s ease; display: flex; flex-direction: column; justify-content: center; z-index: 2; + border-radius: 3px; + padding: 3px; &:hover { - color: gray; + background-color: $light-gray; } } } .collectionSchema-row-wrapper { &.row-above { - border-top: 1px solid red; + border-top: 1px solid $medium-blue; } &.row-below { - border-bottom: 1px solid red; + border-bottom: 1px solid $medium-blue; } &.row-inside { - border: 1px solid red; + border: 2px dashed $medium-blue; } .row-dragging { background-color: blue; @@ -383,24 +419,32 @@ button.add-column { height: unset; } +.collectionSchemaView-cellContents { + width: 100%; +} + .collectionSchemaView-cellWrapper { + display: flex; height: 100%; - padding: 4px; text-align: left; padding-left: 19px; position: relative; + align-items: center; + align-content: center; &:focus { outline: none; } &.editing { padding: 0; + box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3); + transform: scale(1.1); + z-index: 40; input { outline: 0; border: none; - background-color: rgb(255, 217, 217); + background-color: $white; width: 100%; height: 100%; - padding: 2px 3px; min-height: 26px; } } diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx index 631f623c6..3833f968b 100644 --- a/src/client/views/collections/collectionSchema/SchemaTable.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx @@ -194,10 +194,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> { const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up"; const header = <div className="collectionSchemaView-menuOptions-wrapper" style={{ background: col.color, padding: "2px", display: "flex", cursor: "default", height: "100%", }}> {keysDropdown} - <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}> + <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "pointer" }}> <FontAwesomeIcon icon={sortIcon} size="lg" /> </div> - {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>} + {/* {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>} */} </div>; return { |
