Merge branch 'feature/simplify-scss' into 'develop'

Feature/simplify scss

See merge request framasoft/framadate/funky-framadate-front!31
This commit is contained in:
ty kayn 2020-04-21 10:50:26 +02:00
commit 006e506acd
183 changed files with 7788 additions and 7778 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@ image: weboaks/node-karma-protractor-chrome
stages:
- test
- e2e
# - e2e
cache:
paths:
@ -13,17 +13,17 @@ test:
script:
- npm i
- pkill Xvfb
- npm run test
- npm run test:ci
artifacts:
paths:
- coverage/
e2e:
stage: e2e
script:
- npm i
- pkill Xvfb
- npm run e2e
#e2e:
# stage: e2e
# script:
# - npm i
# - pkill Xvfb
# - npm run e2e
pages:
stage: .post

View File

@ -32,7 +32,7 @@
"node_modules/font-awesome/css/font-awesome.css",
"node_modules/primeng/resources/themes/nova-light/theme.css",
"node_modules/primeng/resources/primeng.min.css",
"src/styles.scss"
"src/assets/scss/styles.scss"
],
"scripts": [
"node_modules/marked/lib/marked.js",

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,11 @@
import 'jest-preset-angular';
// const { defaults } = require('jest-config');
//
// module.exports = {
// verbose: true,
// collectCoverage: true,
// collectCoverageFrom: ['src/**/*.ts'],
// // collectCoverageFrom: ['src/**/*.ts'],
// collectCoverageFrom: ['src/app/pages/admin/*.ts'],
// };
Error.stackTraceLimit = 2;

View File

@ -1,102 +1,107 @@
{
"name": "framadate-funky-frontend",
"version": "1.0.0",
"licence": "AGPL-3.0-or-later",
"scripts": {
"ng": "ng",
"start": "ng serve",
"compodoc": "compodoc -p tsconfig.json",
"build": "ng build --crossOrigin=anonymous --prod",
"package": "cat dist/framadate/*.js > dist/framadate/framadate-scripts-bundled.js && ls -l dist/framadate",
"bld:pkg": "npm run build && npm run package",
"build:demo": "ng build --crossOrigin=anonymous --extractCss=true --progress=true --prod && npm run package",
"build:demobliss": "ng build --crossOrigin=anonymous --extractCss=true --baseHref=https://framadate-api.cipherbliss.com --progress=true --prod && npm run package",
"test": "ng test --watch=false",
"lint": "ng lint",
"e2e": "ng e2e",
"format:check": "prettier --list-different \"src/{app,environments,assets}/**/*{.ts,.js,.json,.css,.scss}\"",
"format:all": "prettier --write \"src/**/*.{js,jsx,ts,tsx,md,html,css,scss}\"",
"trans": "ng xi18n --output-path=src/locale --i18n-locale=fr",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"postinstall": "ngcc"
},
"private": false,
"dependencies": {
"@angular/animations": "^9.1.1",
"@angular/cdk": "^9.2.0",
"@angular/common": "^9.0.7",
"@angular/compiler": "^9.0.7",
"@angular/core": "^9.0.7",
"@angular/forms": "^9.0.7",
"@angular/localize": "^9.1.1",
"@angular/platform-browser": "^9.0.7",
"@angular/platform-browser-dynamic": "^9.0.7",
"@angular/router": "^9.0.7",
"@fullcalendar/core": "^4.4.0",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "^4.0.0",
"angular-date-value-accessor": "^1.0.2",
"bulma": "^0.8.2",
"chart.js": "^2.8.0",
"font-awesome": "^4.7.0",
"karma-coverage": "^2.0.1",
"karma-firefox-launcher": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.4",
"ngx-clipboard": "^13.0.0",
"ngx-markdown": "^9.0.0",
"ngx-toaster": "^1.0.1",
"primeicons": "^2.0.0",
"primeng": "^9.0.5",
"quill": "^1.3.7",
"rxjs": "^6.5.5",
"rxjs-compat": "^6.5.5",
"tslib": "^1.11.1",
"zone.js": "^0.10.3"
},
"devDependencies": {
"@angular-builders/jest": "^9.0.1",
"@angular-devkit/build-angular": "^0.901.1",
"@angular/cli": "^9.0.7",
"@angular/compiler-cli": "^9.1.1",
"@angular/language-service": "^9.0.7",
"@babel/core": "^7.9.0",
"@storybook/addon-actions": "^5.3.18",
"@storybook/addon-links": "^5.3.18",
"@storybook/addon-notes": "^5.3.18",
"@storybook/addons": "^5.3.18",
"@storybook/angular": "^5.3.18",
"@types/jasmine": "^3.5.10",
"@types/jasminewd2": "~2.0.8",
"@types/jest": "^25.2.1",
"@types/node": "^13.11.1",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-loader": "^8.1.0",
"compodoc": "^0.0.41",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.3",
"husky": "^4.2.5",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.1",
"jest": "^25.3.0",
"lint-staged": "^10.1.3",
"prettier": "^2.0.4",
"protractor": "~5.4.3",
"ts-node": "~8.8.2",
"typescript": "~3.8.3"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/{app,environments,assets}/**/*.{js,jsx,ts,tsx,md,html,css,scss}": [
"prettier --write",
"git add"
],
"*.js": "eslint --cache --fix"
}
"name": "framadate-funky-frontend",
"version": "1.0.0",
"licence": "AGPL-3.0-or-later",
"scripts": {
"ng": "ng",
"start": "ng serve",
"compodoc": "compodoc -p tsconfig.json",
"build": "ng build --crossOrigin=anonymous --prod",
"package": "cat dist/framadate/*.js > dist/framadate/framadate-scripts-bundled.js && ls -l dist/framadate",
"bld:pkg": "npm run build && npm run package",
"build:demo": "ng build --crossOrigin=anonymous --extractCss=true --progress=true --prod && npm run package",
"build:demobliss": "ng build --crossOrigin=anonymous --extractCss=true --baseHref=https://framadate-api.cipherbliss.com --progress=true --prod && npm run package",
"test": "jest",
"test:watch": "jest --watch",
"test:ci": "jest --runInBand",
"lint": "ng lint",
"e2e": "ng e2e",
"format:check": "prettier --list-different \"src/{app,environments,assets}/**/*{.ts,.js,.json,.css,.scss}\"",
"format:all": "prettier --write \"src/**/*.{js,jsx,ts,tsx,md,html,css,scss}\"",
"trans": "ng xi18n --output-path=src/locale --i18n-locale=fr",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"postinstall": "ngcc"
},
"private": false,
"dependencies": {
"@angular/animations": "^9.1.1",
"@angular/cdk": "^9.2.0",
"@angular/common": "^9.0.7",
"@angular/compiler": "^9.0.7",
"@angular/core": "^9.0.7",
"@angular/forms": "^9.0.7",
"@angular/localize": "^9.1.1",
"@angular/platform-browser": "^9.0.7",
"@angular/platform-browser-dynamic": "^9.0.7",
"@angular/router": "^9.0.7",
"@fullcalendar/core": "^4.4.0",
"@ngx-translate/core": "^12.1.2",
"@ngx-translate/http-loader": "^4.0.0",
"angular-date-value-accessor": "^1.0.2",
"bulma": "^0.8.2",
"chart.js": "^2.8.0",
"font-awesome": "^4.7.0",
"jest-preset-angular": "^8.1.3",
"karma-coverage": "^2.0.1",
"karma-firefox-launcher": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.4",
"ngx-clipboard": "^13.0.0",
"ngx-markdown": "^9.0.0",
"ngx-toaster": "^1.0.1",
"primeicons": "^2.0.0",
"primeng": "^9.0.5",
"quill": "^1.3.7",
"rxjs": "^6.5.5",
"rxjs-compat": "^6.5.5",
"tslib": "^1.11.1",
"zone.js": "^0.10.3"
},
"devDependencies": {
"@angular-builders/jest": "^9.0.1",
"@angular-devkit/build-angular": "^0.901.1",
"@angular/cli": "^9.0.7",
"@angular/compiler-cli": "^9.1.1",
"@angular/language-service": "^9.0.7",
"@babel/core": "^7.9.0",
"@storybook/addon-actions": "^5.3.18",
"@storybook/addon-links": "^5.3.18",
"@storybook/addon-notes": "^5.3.18",
"@storybook/addons": "^5.3.18",
"@storybook/angular": "^5.3.18",
"@types/jasminewd2": "~2.0.8",
"@types/jest": "^25.2.1",
"@types/node": "^13.11.1",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-loader": "^8.1.0",
"compodoc": "^0.0.41",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-prettier": "^3.1.3",
"husky": "^4.2.5",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.1",
"jest": "^25.3.0",
"lint-staged": "^10.1.3",
"prettier": "^2.0.4",
"protractor": "~5.4.3",
"ts-node": "~8.8.2",
"typescript": "~3.8.3"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/{app,environments,assets}/**/*.{js,jsx,ts,tsx,md,html,css,scss}": [
"prettier --write",
"git add"
]
},
"jest": {
"preset": "jest-preset-angular",
"setupFilesAfterEnv": "./jest.config.js"
}
}

View File

@ -1,31 +1,31 @@
<div id="big_container" class="{{ this.config.preferences.themeClass }}">
<header class="big-header">
<div class="container">
<div class="columns">
<div class="column">
<framadate-master-head></framadate-master-head>
</div>
<div class="column">
<framadate-language></framadate-language>
</div>
</div>
</div>
</header>
<header class="big-header">
<div class="container">
<div class="columns">
<div class="column">
<framadate-master-head></framadate-master-head>
</div>
<div class="column">
<framadate-language></framadate-language>
</div>
</div>
</div>
</header>
<main>
<div class="container">
<div class="columns">
<div class="column is-one-quarter">
<framadate-theme-selector></framadate-theme-selector>
<main>
<div class="container">
<div class="columns">
<div class="column is-one-quarter togglable-menu" *ngIf="config.menuVisible">
<framadate-theme-selector></framadate-theme-selector>
<framadate-navigation *ngIf="config.menuVisible" [step]="step"></framadate-navigation>
<framadate-debugger *ngIf="isDevelopmentEnv"></framadate-debugger>
<p-toast position="top-right"></p-toast>
</div>
<div class="column">
<router-outlet></router-outlet>
</div>
</div>
</div>
</main>
<framadate-navigation [step]="step"></framadate-navigation>
<framadate-debugger *ngIf="isDevelopmentEnv"></framadate-debugger>
</div>
<div class="column">
<router-outlet></router-outlet>
</div>
</div>
</div>
</main>
<p-toast position="top-right"></p-toast>
</div>

View File

@ -1,13 +1,13 @@
@charset "UTF-8";
.big-header {
padding: 0.5rem;
padding: 0.5rem;
}
i {
display: block;
display: block;
}
.language-selector {
width: auto;
width: auto;
}

View File

@ -3,29 +3,29 @@ import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
}).compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
}).compileComponents();
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'framadate'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('framadate');
});
it(`should have as title 'framadate'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual('framadate');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to framadate!');
});
it('should render title in a h1 tag', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain('Welcome to framadate!');
});
});

View File

@ -7,49 +7,49 @@ import { ConfigService } from './services/config.service';
import { environment } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
step: string;
isDevelopmentEnv = false;
step: string;
isDevelopmentEnv = false;
constructor(
private translate: TranslateService,
public config: ConfigService,
@Inject(DOCUMENT) private document,
private route: Router
) {
this.detectCurrentTabOnRouteChange();
constructor(
private translate: TranslateService,
public config: ConfigService,
@Inject(DOCUMENT) private document,
private route: Router
) {
this.detectCurrentTabOnRouteChange();
this.isDevelopmentEnv = !environment.production;
}
this.isDevelopmentEnv = !environment.production;
}
detectCurrentTabOnRouteChange() {
this.route.events.subscribe((event: any) => {});
this.route.events
.pipe(filter((event) => event instanceof NavigationStart))
.subscribe((event: NavigationStart) => {
this.scrollGoToTop();
this.updateCurrentTab(event);
// only if there is a poll ID
this.config.fetchPollFromRoute(event);
});
}
detectCurrentTabOnRouteChange() {
this.route.events.subscribe((event: any) => {});
this.route.events
.pipe(filter((event) => event instanceof NavigationStart))
.subscribe((event: NavigationStart) => {
this.scrollGoToTop();
this.updateCurrentTab(event);
// only if there is a poll ID
this.config.fetchPollFromRoute(event);
});
}
scrollGoToTop() {
this.document.documentElement.scrollTop = 0;
}
scrollGoToTop() {
this.document.documentElement.scrollTop = 0;
}
updateCurrentTab(event) {
if (event.url) {
const tab = event.url.split('/');
if (tab && tab[2]) {
this.step = tab[2];
} else {
this.step = 'home';
}
}
}
updateCurrentTab(event) {
if (event.url) {
const tab = event.url.split('/');
if (tab && tab[2]) {
this.step = tab[2];
} else {
this.step = 'home';
}
}
}
}

View File

@ -7,11 +7,11 @@ import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
MissingTranslationHandler,
MissingTranslationHandlerParams,
TranslateLoader,
TranslateModule,
TranslateService,
MissingTranslationHandler,
MissingTranslationHandlerParams,
TranslateLoader,
TranslateModule,
TranslateService,
} from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { ClipboardModule } from 'ngx-clipboard';
@ -60,82 +60,82 @@ import { SelectorComponent } from './ui/selector/selector.component';
import { ThemeSelectorComponent } from './ui/theme-selector/theme-selector.component';
export class MyMissingTranslationHandler implements MissingTranslationHandler {
handle(params: MissingTranslationHandlerParams) {
return 'some value';
}
handle(params: MissingTranslationHandlerParams) {
return 'some value';
}
}
registerLocaleData(localeFr, 'fr');
registerLocaleData(localeEn, 'en');
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http);
return new TranslateHttpLoader(http);
}
@NgModule({
declarations: [
AppComponent,
BaseComponent,
KindComponent,
HeaderComponent,
NavigationComponent,
DatesComponent,
DebuggerComponent,
VisibilityComponent,
ResumeComponent,
PicturesComponent,
AnswersComponent,
EndConfirmationComponent,
CreateOrRetrieveComponent,
VotingSummaryComponent,
VotingGraphComponent,
VotingChoiceComponent,
PasswordComponent,
HomeComponent,
PollGraphicComponent,
AdminComponent,
SelectorComponent,
PollDisplayComponent,
VotingComponent,
VotingCommentComponent,
ResettableInputDirective,
ErasableInputComponent,
CopyTextComponent,
CommentsListComponent,
ChoicesListComponent,
VotingNavigationComponent,
ThemeSelectorComponent,
MasterHeadComponent,
LanguageComponent,
],
imports: [
ConfirmDialogModule,
ClipboardModule,
CommonModule,
BrowserModule,
DialogModule,
DateValueAccessorModule,
BrowserAnimationsModule,
AppRoutingModule,
ToastModule,
MessageModule,
MarkdownModule.forRoot(),
TranslateModule.forRoot({
missingTranslationHandler: {
provide: MissingTranslationHandler,
useClass: MyMissingTranslationHandler,
},
// useDefaultLang: false,
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
}),
HttpClientModule,
FormsModule,
],
providers: [TranslateService, ConfigService, PollService, MessageService, ConfirmationService],
bootstrap: [AppComponent],
declarations: [
AppComponent,
BaseComponent,
KindComponent,
HeaderComponent,
NavigationComponent,
DatesComponent,
DebuggerComponent,
VisibilityComponent,
ResumeComponent,
PicturesComponent,
AnswersComponent,
EndConfirmationComponent,
CreateOrRetrieveComponent,
VotingSummaryComponent,
VotingGraphComponent,
VotingChoiceComponent,
PasswordComponent,
HomeComponent,
PollGraphicComponent,
AdminComponent,
SelectorComponent,
PollDisplayComponent,
VotingComponent,
VotingCommentComponent,
ResettableInputDirective,
ErasableInputComponent,
CopyTextComponent,
CommentsListComponent,
ChoicesListComponent,
VotingNavigationComponent,
ThemeSelectorComponent,
MasterHeadComponent,
LanguageComponent,
],
imports: [
ConfirmDialogModule,
ClipboardModule,
CommonModule,
BrowserModule,
DialogModule,
DateValueAccessorModule,
BrowserAnimationsModule,
AppRoutingModule,
ToastModule,
MessageModule,
MarkdownModule.forRoot(),
TranslateModule.forRoot({
missingTranslationHandler: {
provide: MissingTranslationHandler,
useClass: MyMissingTranslationHandler,
},
// useDefaultLang: false,
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
}),
HttpClientModule,
FormsModule,
],
providers: [TranslateService, ConfigService, PollService, MessageService, ConfirmationService],
bootstrap: [AppComponent],
})
export class AppModule {}

View File

@ -1,63 +1,63 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
providedIn: 'root',
})
export class DateUtilities {
/**
* add some days to a date, to compute intervals
* @param days
* @param date
*/
addDaysToDate(days: number, date: Date) {
date = new Date(date.valueOf());
date.setDate(date.getDate() + days);
return date;
}
/**
* add some days to a date, to compute intervals
* @param days
* @param date
*/
addDaysToDate(days: number, date: Date) {
date = new Date(date.valueOf());
date.setDate(date.getDate() + days);
return date;
}
/**
*
* @param d1
* @param d2
* @param interval
*/
getDatesInRange(d1: Date, d2: Date, interval: number) {
d1 = new Date(d1);
d2 = new Date(d2);
const dates = [];
while (+d1 < +d2) {
dates.push({
literal: this.formateDate(d1),
date_object: d1,
});
d1.setDate(d1.getDate() + interval);
}
return dates.slice(0);
}
/**
*
* @param d1
* @param d2
* @param interval
*/
getDatesInRange(d1: Date, d2: Date, interval: number) {
d1 = new Date(d1);
d2 = new Date(d2);
const dates = [];
while (+d1 < +d2) {
dates.push({
literal: this.formateDate(d1),
date_object: d1,
});
d1.setDate(d1.getDate() + interval);
}
return dates.slice(0);
}
/**
* get the number of days between two dates
* @param d1
* @param d2
*/
dayDiff(d1: Date, d2: Date): Number {
return Number(d2.getTime() - d1.getTime() / 31536000000);
}
/**
* get the number of days between two dates
* @param d1
* @param d2
*/
dayDiff(d1: Date, d2: Date): number {
return Number(d2.getTime() - d1.getTime() / 31536000000);
}
/**
* format a date object to the date format used by the inputs of type date
* YYYY-MM-DD
* @param date
*/
formateDate(date) {
return [
date.getFullYear(),
this.getDoubleDigits(date.getMonth() + 1),
this.getDoubleDigits(date.getDate()),
].join('-');
}
/**
* format a date object to the date format used by the inputs of type date
* YYYY-MM-DD
* @param date
*/
formateDate(date) {
return [
date.getFullYear(),
this.getDoubleDigits(date.getMonth() + 1),
this.getDoubleDigits(date.getDate()),
].join('-');
}
getDoubleDigits(str) {
return ('00' + str).slice(-2);
}
getDoubleDigits(str) {
return ('00' + str).slice(-2);
}
}

View File

@ -5,80 +5,80 @@ import { environment } from '../../environments/environment';
import { DateChoice, defaultAnswers, otherDefaultDates, PollAnswer } from './defaultConfigs';
export interface DateOption {
timeList: any;
literal: string;
date_object?: object;
timeList: any;
literal: string;
date_object?: object;
}
const baseConfigValues = {
pollType: 'dates',
title: '',
description: '',
myName: '',
myEmail: '',
pollType: 'dates',
title: '',
description: '',
myName: '',
myEmail: '',
};
/**
* configuration of the poll, add new fields at will
*/
export class PollConfig {
menuVisible = true;
menuVisible = true;
expiracyDateDefaultInDays = 60;
deletionDateAfterLastModification = 180;
step = 0; // step in the progress of creating a poll
stepMax = 3; // step max in the progress of creating a poll
pollType = 'dates'; // classic or dates
expiracyDateDefaultInDays = 60;
deletionDateAfterLastModification = 180;
step = 0; // step in the progress of creating a poll
stepMax = 3; // step max in the progress of creating a poll
pollType = 'dates'; // classic or dates
title: string = environment.production ? '' : 'titre';
description: string = environment.production ? '' : 'ma description';
myName: string = environment.production ? '' : 'mon pseudo';
myComment: string = environment.production ? '' : 'wouah trop bien framadate!';
isAdmin: boolean = !environment.production;
myVoteStack: any;
myTempVoteStack = 0;
myEmail: string = environment.production ? '' : 'tktest@tktest.com';
myPolls: any = []; // list of retrieved polls from the backend api
/*
title: string = environment.production ? '' : 'titre';
description: string = environment.production ? '' : 'ma description';
myName: string = environment.production ? '' : 'mon pseudo';
myComment: string = environment.production ? '' : 'wouah trop bien framadate!';
isAdmin = !environment.production;
myVoteStack: any;
myTempVoteStack = 0;
myEmail: string = environment.production ? '' : 'tktest@tktest.com';
myPolls: any = []; // list of retrieved polls from the backend api
/*
date specific poll, we have the choice to setup different hours (timeList) for all possible dates (dateList), or use the same hours for all dates
*/
allowSeveralHours = 'true';
// access
visibility = 'link_only'; // visible to anyone with the link:
voteChoices = 'only_yes'; // possible answers to a vote choice: only "yes", "yes, maybe, no"
creationDate = new Date();
expirationDate = ''; // expiracy date
voteStackId = null; // id of the vote stack to update
pollId = null; // id of the current poll when created. data given by the backend api
pollSlug = null; // id of the current poll when created. data given by the backend api
currentPoll; // current poll selected with createPoll or getPoll of ConfigService
passwordAccess = 0;
password = '';
customUrl = ''; // custom slug in the url, must be unique
customUrlIsUnique = null; // given by the backend
urlSlugPublic = null;
urlPublic = environment.production ? '' : environment.baseHref + '/#/poll/id/4';
urlAdmin = environment.baseHref + '/#/admin/d65es45fd45sdf45sd345f312sdf31sgfd345';
adminKey = ''; // key to change config of the poll
owner_modifier_token = ''; // key to change a vote stack
canModifyAnswers = true; // bool for the frontend selector
whoModifiesAnswers = 'everybody'; // everybody, self, nobody (= just admin)
whoCanChangeAnswers = 'everybody'; // everybody, self, nobody (= just admin)
dateList: any = otherDefaultDates; // sets of days as strings, config to set identical time for days in a special days poll
timeList: DateChoice[] = otherDefaultDates; // ranges of time expressed as strings
allowSeveralHours = 'true';
// access
visibility = 'link_only'; // visible to anyone with the link:
voteChoices = 'only_yes'; // possible answers to a vote choice: only "yes", "yes, maybe, no"
creationDate = new Date();
expirationDate = ''; // expiracy date
voteStackId = null; // id of the vote stack to update
pollId = null; // id of the current poll when created. data given by the backend api
pollSlug = null; // id of the current poll when created. data given by the backend api
currentPoll; // current poll selected with createPoll or getPoll of ConfigService
passwordAccess = 0;
password = '';
customUrl = ''; // custom slug in the url, must be unique
customUrlIsUnique = null; // given by the backend
urlSlugPublic = null;
urlPublic = environment.production ? '' : environment.baseHref + '/#/poll/id/4';
urlAdmin = environment.baseHref + '/#/admin/d65es45fd45sdf45sd345f312sdf31sgfd345';
adminKey = ''; // key to change config of the poll
owner_modifier_token = ''; // key to change a vote stack
canModifyAnswers = true; // bool for the frontend selector
whoModifiesAnswers = 'everybody'; // everybody, self, nobody (= just admin)
whoCanChangeAnswers = 'everybody'; // everybody, self, nobody (= just admin)
dateList: any = otherDefaultDates; // sets of days as strings, config to set identical time for days in a special days poll
timeList: DateChoice[] = otherDefaultDates; // ranges of time expressed as strings
answers: PollAnswer[] = defaultAnswers;
// front end choices
themeChoices: string[] = ['light-watermelon', 'dark-crystal', 'hot-covid'];
themeSelected = 0;
themeClass = 'theme-light-watermelon';
// modals
displayConfirmVoteModalAdmin = false;
answers: PollAnswer[] = defaultAnswers;
// front end choices
themeChoices: string[] = ['light-watermelon', 'dark-crystal', 'hot-covid'];
themeSelected = 0;
themeClass = 'theme-light-watermelon';
// modals
displayConfirmVoteModalAdmin = false;
resetConfig() {
const self = this;
Object.keys(baseConfigValues).forEach((key) => {
self[key] = baseConfigValues[key];
});
}
resetConfig() {
const self = this;
Object.keys(baseConfigValues).forEach((key) => {
self[key] = baseConfigValues[key];
});
}
}

View File

@ -3,73 +3,73 @@ import { PollConfig } from './PollConfig';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
providedIn: 'root',
})
export class PollUtilities {
// utils functions
/**
* generate unique id to have a default url for future poll
*/
makeUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
// utils functions
/**
* generate unique id to have a default url for future poll
*/
makeUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
/**
* make a uniq slug for the current poll creation
* @param str
*/
makeSlug(config: PollConfig) {
let str = '';
str =
config.creationDate.getFullYear() +
'_' +
(config.creationDate.getMonth() + 1) +
'_' +
config.creationDate.getDate() +
'_' +
config.myName +
'_' +
config.title;
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
/**
* make a uniq slug for the current poll creation
* @param str
*/
makeSlug(config: PollConfig) {
let str = '';
str =
config.creationDate.getFullYear() +
'_' +
(config.creationDate.getMonth() + 1) +
'_' +
config.creationDate.getDate() +
'_' +
config.myName +
'_' +
config.title;
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';
var to = 'aaaaeeeeiiiioooouuuunc------';
for (var i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
// remove accents, swap ñ for n, etc
const from = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;';
const to = 'aaaaeeeeiiiioooouuuunc------';
for (let i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
str = str
.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
str = str
.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
return str;
}
return str;
}
/**
* prepare headers like the charset and json type for any call to the backend
* @param bodyContent
*/
makeHeaders(bodyContent?: any) {
const headerDict = {
Charset: 'UTF-8',
'Content-Type': 'application/json',
Accept: 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Origin': '*',
};
/**
* prepare headers like the charset and json type for any call to the backend
* @param bodyContent
*/
makeHeaders(bodyContent?: any) {
const headerDict = {
Charset: 'UTF-8',
'Content-Type': 'application/json',
Accept: 'application/json',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Origin': '*',
};
const requestOptions = {
headers: new HttpHeaders(headerDict),
body: bodyContent,
};
const requestOptions = {
headers: new HttpHeaders(headerDict),
body: bodyContent,
};
return requestOptions;
}
return requestOptions;
}
}

View File

@ -1,21 +1,21 @@
export interface DateChoice {
literal: string;
timeList: TimeSlices[];
date_object: Date;
literal: string;
timeList: TimeSlices[];
date_object: Date;
}
export interface TimeSlices {
literal: string;
literal: string;
}
export interface PollAnswer {
id: number;
text: string;
url: string;
file: string;
literal: string;
date_object: Date;
timeList: TimeSlices[];
id: number;
text: string;
url: string;
file: string;
literal: string;
date_object: Date;
timeList: TimeSlices[];
}
const currentYear = new Date().getFullYear();
@ -24,84 +24,84 @@ const currentDay = new Date().getDate();
export const basicSlicesOfDay: TimeSlices[] = [{ literal: 'matin' }, { literal: 'midi' }, { literal: 'soir' }];
export const otherSlicesOfDay: TimeSlices[] = [
{ literal: 'aux aurores' },
{ literal: 'au petit dej' },
{ literal: 'au deuxième petit dej des hobbits' },
{ literal: 'aux aurores' },
{ literal: 'au petit dej' },
{ literal: 'au deuxième petit dej des hobbits' },
];
export const defaultTimeOfDay: TimeSlices[] = (() => {
return [...basicSlicesOfDay];
return [...basicSlicesOfDay];
})();
export const otherTimeOfDay: TimeSlices[] = (() => {
return [...otherSlicesOfDay];
return [...otherSlicesOfDay];
})();
export const moreTimeOfDay: TimeSlices[] = (() => {
return [...otherSlicesOfDay];
return [...otherSlicesOfDay];
})();
export const defaultDates: DateChoice[] = [
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
];
export const otherDefaultDates: DateChoice[] = [
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(currentYear, currentMonth, currentDay + 1),
timeList: otherTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: moreTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: defaultTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(currentYear, currentMonth, currentDay + 1),
timeList: otherTimeOfDay,
},
{
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: moreTimeOfDay,
},
];
export const defaultAnswers: PollAnswer[] = [
{
id: 0,
text: 'réponse de démo 1',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: otherSlicesOfDay,
},
{
id: 1,
text: 'réponse 2',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: basicSlicesOfDay,
},
{
id: 2,
text: 'la réponse D',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: otherSlicesOfDay,
},
{
id: 0,
text: 'réponse de démo 1',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay}`,
date_object: new Date(),
timeList: otherSlicesOfDay,
},
{
id: 1,
text: 'réponse 2',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 1}`,
date_object: new Date(),
timeList: basicSlicesOfDay,
},
{
id: 2,
text: 'la réponse D',
file: '',
url:
'https://mastodon.cipherbliss.com/system/media_attachments/files/001/439/118/original/6fcf149bd902841b.png?1579471574',
literal: `${currentYear}-${currentMonth}-${currentDay + 2}`,
date_object: new Date(),
timeList: otherSlicesOfDay,
},
];

View File

@ -1,24 +1,24 @@
export var graphOptions = {
legend: { display: false },
scales: {
xAxes: [
{
gridLines: { drawBorder: false, display: false },
display: false,
stacked: true,
ticks: {
beginAtZero: true,
maxRotation: 0,
minRotation: 0,
},
},
],
yAxes: [
{
gridLines: { drawBorder: true, display: false },
display: true,
stacked: true,
},
],
},
legend: { display: false },
scales: {
xAxes: [
{
gridLines: { drawBorder: false, display: false },
display: false,
stacked: true,
ticks: {
beginAtZero: true,
maxRotation: 0,
minRotation: 0,
},
},
],
yAxes: [
{
gridLines: { drawBorder: true, display: false },
display: true,
stacked: true,
},
],
},
};

View File

@ -1,11 +1,11 @@
export const mockChoice = {
id: 11,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
text: 'Les mondes engloutis',
url: null,
answer: null,
id: 11,
date: {
date: '2020-01-30 12:25:13.000000',
timezone_type: 3,
timezone: 'Europe/Berlin',
},
text: 'Les mondes engloutis',
url: null,
answer: null,
};

View File

@ -1,22 +1,22 @@
export const mockComments = [
{
pseudo: 'Bulbizarre',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text:
'Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark\n' +
' Skitty Rock Luxio Surskit. Glacier Badge',
},
{
pseudo: 'Marylin',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text: "j'ai vu de la lumière o_o",
},
{
pseudo: 'Bulbizarre',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text:
'Pokem ipsum dolor sit amet Electric Cottonee Scratch Leech Life Ice Berry Ducklett. Leaf Green Durant Zoroark\n' +
' Skitty Rock Luxio Surskit. Glacier Badge',
},
{
pseudo: 'Marylin',
date: {
date: '2020-01-22 16:00:22.000000',
timezone_type: 3,
timezone: 'Europe/Paris',
},
text: "j'ai vu de la lumière o_o",
},
];

View File

@ -1,52 +1,52 @@
export const mockGraphConfig = {
step: 0,
stepMax: 3,
pollType: 'special dates',
title: '',
description: '',
myName: '',
visibility: 'link_only',
// date specific poll
allowSeveralHours: 'true',
dateLgfgfgfgist: ['jeudi', 'vendredi', 'samedi'], // sets of days as strings
timeList: ['08:00', '08:30', '09:00'], // ranges of time expressed as strings
answers: [
{
id: 0,
text: 'no',
},
step: 0,
stepMax: 3,
pollType: 'special dates',
title: '',
description: '',
myName: '',
visibility: 'link_only',
// date specific poll
allowSeveralHours: 'true',
dateLgfgfgfgist: ['jeudi', 'vendredi', 'samedi'], // sets of days as strings
timeList: ['08:00', '08:30', '09:00'], // ranges of time expressed as strings