mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-21 15:54:22 +01:00
(ui) Update layout
This commit is contained in:
parent
b9d86aecdc
commit
554ed083d0
@ -30,6 +30,7 @@ import ProductLib from '../../lib/product';
|
|||||||
import { UIRouter } from '@uirouter/angularjs';
|
import { UIRouter } from '@uirouter/angularjs';
|
||||||
import SettingAPI from '../../api/setting';
|
import SettingAPI from '../../api/setting';
|
||||||
import { SelectOption } from '../../models/select';
|
import { SelectOption } from '../../models/select';
|
||||||
|
import { CaretDoubleUp } from 'phosphor-react';
|
||||||
|
|
||||||
declare const Application: IApplication;
|
declare const Application: IApplication;
|
||||||
|
|
||||||
@ -66,7 +67,6 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser, uiRouter
|
|||||||
const [resources, setResources] = useImmer<ProductResourcesFetching>(storeInitialResources);
|
const [resources, setResources] = useImmer<ProductResourcesFetching>(storeInitialResources);
|
||||||
const [machinesModule, setMachinesModule] = useState<boolean>(false);
|
const [machinesModule, setMachinesModule] = useState<boolean>(false);
|
||||||
const [categoriesTree, setCategoriesTree] = useState<CategoryTree[]>([]);
|
const [categoriesTree, setCategoriesTree] = useState<CategoryTree[]>([]);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const [filtersPanel, setFiltersPanel] = useState<boolean>(false);
|
const [filtersPanel, setFiltersPanel] = useState<boolean>(false);
|
||||||
const [pageCount, setPageCount] = useState<number>(0);
|
const [pageCount, setPageCount] = useState<number>(0);
|
||||||
const [productsCount, setProductsCount] = useState<number>(0);
|
const [productsCount, setProductsCount] = useState<number>(0);
|
||||||
@ -241,11 +241,14 @@ const Store: React.FC<StoreProps> = ({ onError, onSuccess, currentUser, uiRouter
|
|||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
<aside className={`store-filters ${filtersPanel ? '' : 'collapsed'}`}>
|
<aside className={`store-filters ${filtersPanel ? '' : 'collapsed'}`}>
|
||||||
<div className='grp'>
|
|
||||||
<div className="categories">
|
|
||||||
<header>
|
<header>
|
||||||
<h3>{t('app.public.store.products.filter_categories')}</h3>
|
<h3>{t('app.public.store.products.filter_categories')}</h3>
|
||||||
|
<div className="grpBtn">
|
||||||
|
<CaretDoubleUp className='filters-toggle' size={16} weight="bold" onClick={() => setFiltersPanel(!filtersPanel)} />
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
<div className='grp'>
|
||||||
|
<div className="categories">
|
||||||
<div className="group u-scrollbar">
|
<div className="group u-scrollbar">
|
||||||
{categoriesTree.map(c =>
|
{categoriesTree.map(c =>
|
||||||
<div key={c.parent.id} className={`parent ${selectedCategory?.id === c.parent.id || selectedCategory?.parent_id === c.parent.id ? 'is-active' : ''}`}>
|
<div key={c.parent.id} className={`parent ${selectedCategory?.id === c.parent.id || selectedCategory?.parent_id === c.parent.id ? 'is-active' : ''}`}>
|
||||||
|
@ -103,7 +103,9 @@
|
|||||||
@import "modules/profile-completion/completion-header-info";
|
@import "modules/profile-completion/completion-header-info";
|
||||||
@import "modules/profile-completion/profile-form-option";
|
@import "modules/profile-completion/profile-form-option";
|
||||||
@import "modules/profile-custom-fields/profile-custom-fields-list";
|
@import "modules/profile-custom-fields/profile-custom-fields-list";
|
||||||
|
@import "modules/projects/project-card";
|
||||||
@import "modules/projects/projects-setting.scss";
|
@import "modules/projects/projects-setting.scss";
|
||||||
|
@import "modules/projects/projects";
|
||||||
@import "modules/select-gateway-modal";
|
@import "modules/select-gateway-modal";
|
||||||
@import "modules/settings/boolean-setting";
|
@import "modules/settings/boolean-setting";
|
||||||
@import "modules/settings/check-list-setting";
|
@import "modules/settings/check-list-setting";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.machine-card {
|
.machine-card {
|
||||||
background-color: #fff;
|
background-color: var(--gray-soft-lightest);
|
||||||
border: 1px solid #ddd;
|
border: 1px solid var(--gray-soft-dark);
|
||||||
border-radius: var(--border-radius);
|
border-radius: var(--border-radius);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
.project-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: var(--gray-soft-lightest);
|
||||||
|
border: 1px solid var(--gray-soft-dark);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
overflow: hidden;
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--gray-hard);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-image {
|
||||||
|
@include imageRatio(50%);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
border-bottom: 1px solid var(--gray-soft-dark);
|
||||||
|
}
|
||||||
|
.project-info {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
padding: 1.6rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.openlab {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.8rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--main);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
app/frontend/src/stylesheets/modules/projects/projects.scss
Normal file
47
app/frontend/src/stylesheets/modules/projects/projects.scss
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
.projects {
|
||||||
|
max-width: calc(1600px + 6rem);
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 3rem 3rem 6rem;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 2.4rem 3.2rem;
|
||||||
|
|
||||||
|
&-filters,
|
||||||
|
.grp {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.6rem;
|
||||||
|
header {
|
||||||
|
@include header();
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
.switch {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.keywords {
|
||||||
|
display: flex;
|
||||||
|
input {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
|
||||||
|
gap: 3.2rem;
|
||||||
|
& > span { grid-column: 1/-1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
grid-template-columns: 1fr 3fr;
|
||||||
|
&-list { grid-column: 2/-1; }
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.collapsed {
|
&.collapsed {
|
||||||
header .grpBtn svg { transform: rotateZ(-180deg); }
|
header .grpBtn .filters-toggle { transform: rotateZ(-180deg); }
|
||||||
header .grpBtn button { display: flex; }
|
header .grpBtn button { display: flex; }
|
||||||
.grp {
|
.grp {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
@ -26,7 +26,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
button { display: none; }
|
button { display: none; }
|
||||||
svg {
|
.filters-toggle {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 250ms ease-in-out;
|
transition: transform 250ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,37 @@
|
|||||||
line-height: 1.18;
|
line-height: 1.18;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin header($sticky: false) {
|
||||||
|
padding: 2.4rem 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
@if $sticky {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
margin-top: 1px;
|
||||||
|
padding: 2.4rem 0 4rem;
|
||||||
|
background: linear-gradient(180deg, var(--gray-soft-lightest) 80%, transparent);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
@include title-lg;
|
||||||
|
color: var(--gray-hard-darkest) !important;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
@include text-lg(600);
|
||||||
|
color: var(--gray-hard-darkest) !important;
|
||||||
|
}
|
||||||
|
.grpBtn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.6rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Text Editor
|
// Text Editor
|
||||||
@mixin editor {
|
@mixin editor {
|
||||||
*:first-child {
|
*:first-child {
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="projects">
|
||||||
<section class="m-lg">
|
<div class="projects-filters">
|
||||||
<div class="row m-b-md">
|
<header>
|
||||||
<div class="col-md-12 m-b">
|
<h3>Filter</h3>
|
||||||
<a href="javascript:void(0);" class="text-sm pull-right reinit-filters" name="button" ng-click="resetFiltersAndTriggerSearch()" ng-show="!openlab.searchOverWholeNetwork"><i class="fa fa-refresh"></i> {{ 'app.public.projects_list.reset_all_filters' | translate }}</a>
|
<a href="javascript:void(0);" class="fab-button is-black" name="button" ng-click="resetFiltersAndTriggerSearch()" ng-show="!openlab.searchOverWholeNetwork">{{ 'app.public.projects_list.reset_all_filters' | translate }}</a>
|
||||||
|
</header>
|
||||||
<span ng-if="openlab.projectsActive" uib-tooltip="{{ 'app.public.projects_list.tooltip_openlab_projects_switch' | translate }}" tooltip-trigger="mouseenter">
|
<span class="switch" ng-if="openlab.projectsActive" uib-tooltip="{{ 'app.public.projects_list.tooltip_openlab_projects_switch' | translate }}" tooltip-trigger="mouseenter">
|
||||||
<label for="searchOverWholeNetwork" class="control-label m-r text-sm" translate>{{ 'app.public.projects_list.search_over_the_whole_network' }}</label>
|
<label for="searchOverWholeNetwork" class="control-label text-sm" translate>{{ 'app.public.projects_list.network_search' }}</label>
|
||||||
<input bs-switch
|
<input bs-switch
|
||||||
ng-model="openlab.searchOverWholeNetwork"
|
ng-model="openlab.searchOverWholeNetwork"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -36,91 +36,53 @@
|
|||||||
switch-animate="true"
|
switch-animate="true"
|
||||||
ng-change="searchOverWholeNetworkChanged()"
|
ng-change="searchOverWholeNetworkChanged()"
|
||||||
/>
|
/>
|
||||||
{{ searchOverWholeNetwork }}
|
|
||||||
</span>
|
</span>
|
||||||
<form class="form-inline m-t text-center" role="form" ng-submit="setUrlQueryParams(search) && triggerSearch()">
|
|
||||||
<div class="form-group">
|
<form role="form" ng-submit="setUrlQueryParams(search) && triggerSearch()">
|
||||||
<div class="input-group">
|
<div class="keywords">
|
||||||
<div class="input-group-addon"><i class="fa fa-search"></i></div>
|
|
||||||
<input type="search" class="form-control" placeholder="{{ 'app.public.projects_list.keywords' | translate }}" ng-model="search.q"/>
|
<input type="search" class="form-control" placeholder="{{ 'app.public.projects_list.keywords' | translate }}" ng-model="search.q"/>
|
||||||
<div class="input-group-btn">
|
<button type="submit" class="fab-button fab-button--icon-only is-secondary"><i class="fas fa-search"></i></button>
|
||||||
<button type="submit" class="btn btn-warning" translate>{{ 'app.public.projects_list.search' }}</button>
|
<!--<button type="submit" class="btn btn-warning" translate>{{ 'app.public.projects_list.search' }}</button>-->
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
<div class="col-md-12" ng-if="!openlab.searchOverWholeNetwork">
|
<div class="grp" ng-if="!openlab.searchOverWholeNetwork">
|
||||||
<div class="col-md-3 m-b" ng-show="isAuthenticated()">
|
<select ng-show="isAuthenticated()" ng-model="search.from" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control">
|
||||||
<select ng-model="search.from" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control">
|
|
||||||
<option value="" translate>{{ 'app.public.projects_list.all_projects' }}</option>
|
<option value="" translate>{{ 'app.public.projects_list.all_projects' }}</option>
|
||||||
<option value="mine" translate>{{ 'app.public.projects_list.my_projects' }}</option>
|
<option value="mine" translate>{{ 'app.public.projects_list.my_projects' }}</option>
|
||||||
<option value="collaboration" translate>{{ 'app.public.projects_list.projects_to_whom_i_take_part_in' }}</option>
|
<option value="collaboration" translate>{{ 'app.public.projects_list.projects_to_whom_i_take_part_in' }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
<div class="col-md-3 m-b">
|
|
||||||
<select ng-model="search.machine_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="m.id as m.name for m in machines">
|
<select ng-model="search.machine_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="m.id as m.name for m in machines">
|
||||||
<option value="" translate>{{ 'app.public.projects_list.all_machines' }}</option>
|
<option value="" translate>{{ 'app.public.projects_list.all_machines' }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-2 m-b">
|
|
||||||
<select ng-model="search.theme_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="t.id as t.name for t in themes">
|
<select ng-model="search.theme_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="t.id as t.name for t in themes">
|
||||||
<option value="" translate>{{ 'app.public.projects_list.all_themes' }}</option>
|
<option value="" translate>{{ 'app.public.projects_list.all_themes' }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-2 m-b">
|
|
||||||
<select ng-model="search.component_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="t.id as t.name for t in components">
|
<select ng-model="search.component_id" ng-change="setUrlQueryParams(search) && triggerSearch()" class="form-control" ng-options="t.id as t.name for t in components">
|
||||||
<option value="" translate>{{ 'app.public.projects_list.all_materials' }}</option>
|
<option value="" translate>{{ 'app.public.projects_list.all_materials' }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
<div class="col-md-2 m-b">
|
|
||||||
<status-filter on-filter-change="onStatusChange" current-status-index="search.status_id"/>
|
<status-filter on-filter-change="onStatusChange" current-status-index="search.status_id"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="projects-list">
|
||||||
<span class="col-md-12" ng-show="projects && (projects.length == 0)"> {{ 'app.public.projects_list.project_search_result_is_empty' | translate }} </span>
|
<span ng-show="projects && (projects.length == 0)"> {{ 'app.public.projects_list.project_search_result_is_empty' | translate }} </span>
|
||||||
<div class="col-xs-12 col-sm-6 col-md-3" ng-repeat="project in projects" ng-click="showProject(project)">
|
<div class="project-card" ng-repeat="project in projects" ng-click="showProject(project)">
|
||||||
|
<div class="project-image" style="background-image: url({{project.project_image}});">
|
||||||
<div class="card card-project">
|
|
||||||
|
|
||||||
<div class="card-header">
|
|
||||||
<div class="card-header-bg" style="background-image: url({{project.project_image}});">
|
|
||||||
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon" bs-holder ng-if="!project.project_image">
|
<img src="data:image/png;base64," data-src="holder.js/100%x100%/text:/font:'Font Awesome 5 Free'/icon" bs-holder ng-if="!project.project_image">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<div class="project-info">
|
||||||
|
|
||||||
<div class="card-block">
|
|
||||||
<h3 class="card-meta" ng-if="openlab.searchOverWholeNetwork"><i class="fa fa-tag"></i> {{ project.app_name }}</h3>
|
|
||||||
<h1 class="card-title">{{project.name}}</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<span class="badge" ng-if="project.state == 'draft'" translate>{{ 'app.public.projects_list.rough_draft' }}</span>
|
<span class="badge" ng-if="project.state == 'draft'" translate>{{ 'app.public.projects_list.rough_draft' }}</span>
|
||||||
</div>
|
<p class="name">{{project.name}}</p>
|
||||||
|
<span class="openlab" ng-if="openlab.searchOverWholeNetwork"><i class="fa fa-tag"></i> {{ project.app_name }}</span>
|
||||||
<div class="card-overlay">
|
|
||||||
<div class="btn-group">
|
|
||||||
<div class="btn btn-default" ng-click="showProject(project)">
|
|
||||||
<i ng-class="{'fa fa-external-link' : (openlab.searchOverWholeNetwork && project.app_id != openlabAppId) }"></i> {{ 'app.shared.buttons.consult' | translate }}
|
|
||||||
</div>
|
|
||||||
<div class="btn btn-default" ui-sref="app.logged.projects_edit({id:project.id})" ng-if="isAuthorized('admin') && !openlab.searchOverWholeNetwork">
|
|
||||||
<i class="fa fa-edit"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 text-center">
|
|
||||||
<a class="btn btn-warning" ng-click="loadMore()" ng-if="projectsPagination.hasNextPage()" translate>{{ 'app.public.projects_list.load_next_projects' }}</a>
|
<a class="btn btn-warning" ng-click="loadMore()" ng-if="projectsPagination.hasNextPage()" translate>{{ 'app.public.projects_list.load_next_projects' }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
@ -169,13 +169,12 @@ en:
|
|||||||
projects_list:
|
projects_list:
|
||||||
the_fablab_projects: "The projects"
|
the_fablab_projects: "The projects"
|
||||||
add_a_project: "Add a project"
|
add_a_project: "Add a project"
|
||||||
search_over_the_whole_network: "Search over the whole Fab-manager network"
|
network_search: "Fab-manager network"
|
||||||
tooltip_openlab_projects_switch: "The search over the whole network lets you search over the projects of every Fab-manager using this feature !"
|
tooltip_openlab_projects_switch: "The search over the whole network lets you search over the projects of every Fab-manager using this feature !"
|
||||||
openlab_search_not_available_at_the_moment: "Search over the whole network is not available at the moment. You still can search over the projects of this platform."
|
openlab_search_not_available_at_the_moment: "Search over the whole network is not available at the moment. You still can search over the projects of this platform."
|
||||||
project_search_result_is_empty: "Sorry, we found no results matching your search criteria."
|
project_search_result_is_empty: "Sorry, we found no results matching your search criteria."
|
||||||
reset_all_filters: "Reset all filters"
|
reset_all_filters: "Clear all"
|
||||||
keywords: "Keywords"
|
keywords: "Keywords"
|
||||||
search: "Search"
|
|
||||||
all_projects: "All projects"
|
all_projects: "All projects"
|
||||||
my_projects: "My projects"
|
my_projects: "My projects"
|
||||||
projects_to_whom_i_take_part_in: "Projects to whom I take part in"
|
projects_to_whom_i_take_part_in: "Projects to whom I take part in"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user