рдЖрд╕рд╛рди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ: рдПрдХ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдореЗрдВ рдЧрд┐рдЯрд▓реИрдм рдХреЗ рд▓рд┐рдП рдХрд╛рдирдмрди рдмреЛрд░реНрдб

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╕реЛрдорд╡рд╛рд░ рд╢реБрд░реВ рд╣реБрдЖ:

рдиреЗрддрд╛ (рдкреА): рдпрд╣ рдЖрдкрдХреА рдЯреАрдо рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреМрди рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред
I (I): рд╣рд╛рдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдРрд╕рд╛ рдЙрдкрдХрд░рдг рдирд╣реАрдВ рд╣реИ рдЬреЛ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдХрд╛рд░реНрдп рдХреА рд╕рд╛рдорд╛рдиреНрдп рддрд╕реНрд╡реАрд░ рдХреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд рдХрд░реЗрдЧрд╛ред рд╣рд┐рдЯрд▓реИрдм рдореЗрдВ рдХрд╛рдирдмрди рдмреЛрд░реНрдб рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ рдХреЗрд╡рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рд╕рдореВрд╣реЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╣реИрдВред рдПрдХ рдЖрдо рдХрд╛рдирдмрди рдмреЛрд░реНрдб рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдЧрд╛ред
R: рдлрд┐рд░ рдПрдХ рдмреЛрд░реНрдб рдмрдирд╛рддреЗ рд╣реИрдВред
рдореИрдВ: рд╕реБрдмрд╣ рддрдХ рдпрд╣ рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЬрд▓реНрджреА рдпрд╛ рдмрд╛рдж рдореЗрдВ, рдПрдХ рд╢реБрд░реБрдЖрддреА рдЯреАрдо рд▓реАрдбрд░ рдХреЗ рдЬреАрд╡рди рдореЗрдВ рд╡рд╣ рдкрд▓ рдЖрддрд╛ рд╣реИ рдЬрдм рдЙрд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЙрд╕рдХреА рдЯреАрдо рдХреЛ рдПрдХ рдХрд╛рдмрди рдмреЛрд░реНрдб рдХреА рдЬрд░реВрд░рдд рд╣реИред рдпрд╣ рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд┐рдпрдВрддреНрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХреЛ рджреВрд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рджреЗрддрд╛ рд╣реИред рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдПрдХ рдЪреБрдВрдмрдХреАрдп рдмреЛрд░реНрдб, рдмрд╣реБ-рд░рдВрдЧреАрди рд╕реНрдЯрд┐рдХрд░ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдФрд░ рдмреЛрд░реНрдб рдХреЗ рд▓рд┐рдП рдорд╛рд░реНрдХрд░реЛрдВ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рдЦрд░реАрджрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдмрдВрдзрдХ рдХреЗ рд╕рдмрд╕реЗ рдХрдо рдЕрдиреБрд░реЛрдз рд╕реЗ рд╣рд▓ рд╣реЛрддреА рд╣реИред рдЦреИрд░, рдпрд╛ рдЬреАрд░рд╛ рдЬреИрд╕реА рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рдЯреАрдо рдореЗрдВ рд░рд┐рдореЛрдЯ рдкрд░ рдПрдХ рдбреЗрд╡рд▓рдкрд░ рд╣реИ, рдФрд░ рдПрдХ рдмрдВрдж рд╕рд░реНрдХрд┐рдЯ рдореЗрдВ рдЧрд┐рдЯрд▓реИрдм (рд╕реВрдЪрдирд╛ рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдЗрдВрдЯрд░рдиреЗрдЯ рд╕реЗ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ), рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рджреЛ рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рд╕реЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЪреБрдирдирд╛ рдкрдбрд╝рд╛:

рдХ) рдпрд╛рдВрддреНрд░рд┐рдХ рд╣рд╛рде рдФрд░ рдЙрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛ рдирд┐рд░реНрдорд╛рдг, рдЬреЛ рджреВрд░ рд╕реЗ рд╕реНрдЯрд┐рдХрд░ рдХреЛ рдмреЛрд░реНрдб рдкрд░ рдлрд┐рд░ рд╕реЗ рдЪрд┐рдкрдХрд╛ рджреЗрдЧрд╛, рдЬрдмрдХрд┐ рдирд┐рд░реНрдгрдп рдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ рджреБрд░реНрдЧрдо рд╕рд╣рдпреЛрдЧреА рдХреЗ рд▓рд┐рдП рд╕реНрдЯрд┐рдХрд░ рдкрд░ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдЕрдиреБрдЪрд┐рдд рд╣реИ;
b) рдПрдХ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ kanban рдмреЛрд░реНрдб рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛ рд╣рдорд╛рд░реЗ рд╣рд┐рдЯрд▓реИрдм рд╕реЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдПрдХрддреНрд░рд┐рдд рдХрд░реЗрдЧрд╛ред

рдмреЗрд╢рдХ, рдЖрддреНрдорд╛ рднреМрддрд┐рдХ рдмреЛрд░реНрдб рдХреА рдЯреНрдпреВрдм рдХреЗ рдЦрд┐рд▓рд╛рдл рд░рдЦрддреА рд╣реИред рдореИрдВ рднреА рдПрдХ рдпрд╛рдВрддреНрд░рд┐рдХ рд╣рд╛рде рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рд░реВрдк рдореЗрдВ DualShock 4 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЦреБрдж рдЕрдЧрд▓реА рд╕реБрдмрд╣ рдХреА рд╕рдордп рд╕реАрдорд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдПрдХ рд╕реМрд▓рд╕ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдорд┐рд▓рдирд╛ рдерд╛ред


рдХрд╣рд╛рдиреА рдХреЗ рддрдХрдиреАрдХреА рднрд╛рдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рдХреИрд╕реЗ Onlanta рдореЗрдВ gitlab рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╣рд┐рдЯрд▓реИрдм рдореЗрдВ рд╕рдореВрд╣ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдВрддрд░рд┐рдХ / рдмрд╛рд╣рд░реА рдЧреНрд░рд╛рд╣рдХ рдпрд╛ рдПрдХ рдЕрд▓рдЧ рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕реЗрд╡рд╛ рдХреЗ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рднрдВрдбрд╛рд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдмрд┐рд▓рд┐рдВрдЧ рдХрдВрдЯреНрд░реЛрд▓ рдкреИрдирд▓ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЪрд╛рд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдБ рд╕реЗрд╡рд╛рдПрдБ рдФрд░ рд╡реЗрдм рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИрдВ, рдФрд░ рдПрдХ рд╡рд┐рдкрдгрди рд╕рдореВрд╣ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдХреЙрд░реНрдкреЛрд░реЗрдЯ рд╕рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ, amoCRM рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ microservice, рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реИрдВрдбрд┐рдВрдЧ рдкреГрд╖реНрда рдФрд░ рдЗрддрдиреЗ рдкрд░ред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╣рдорд╛рд░реЗ рдиреМ рд╕рдХреНрд░рд┐рдп рд╕рдореВрд╣ рд╣реИрдВ, рдФрд░ рдХрдо рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕рднреА рд╕рдореВрд╣реЛрдВ рдореЗрдВ рднрд╛рдЧ рд▓реЗрддреЗ рд╣реИрдВред

рдФрд░ рд╣рдо рд╕рднреА рдХреА рдЬрд░реВрд░рдд рдПрдХ рдкреЗрдЬ рдерд╛, рдЬреЛ рд╕рднреА рд╕рдореВрд╣реЛрдВ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рд╕реЗ рд╣рд┐рдЯрд▓реИрдм рдХреЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдерд╛, рд▓реЗрдХрд┐рди рдЧрд┐рдЯрд▓реИрдм рдореЗрдВ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдирд╣реАрдВ рд╣реИред рддреНрд╡рд░рд┐рдд Google рдиреЗ рдПрдХ рд╕реНрдЯреИрдВрдбрдЕрд▓реЛрди рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬрдиреЗ рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХреА, рдЗрд╕рд▓рд┐рдП

рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:


- Node.js рдкрд░ рдмреИрдХрдПрдВрдб - рдЧрд┐рдЯрд▓реИрдм рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП;
- Vue.js рдкрд░ рдХреНрд▓рд╛рдЗрдВрдЯ - рдЗрд╕реЗ рдЬрд▓реНрджреА рдФрд░ рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП;
- рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдм рдореМрд╕рдо, рдмрд┐рд▓реНрдХреБрд▓!
- PostgreSQL - рдЬрд╣рд╛рдВ рд╣рдо рдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗ;
- рдХрд╛рдо рдХреЗ рд╕рдордп рдХреЗ 8 рдШрдВрдЯреЗ;
- рдЕрдЪреНрдЫрд╛ рдореВрдбред

рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╢рд░реНрдд рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рдХрд╛рд╕ рдЖрд╕рд╛рди рдФрд░ рдордЬреЗрджрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЪрд▓реЛ рдЗрд╕реЗ "рдЖрд╕рд╛рди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ" рдХрд╣реЗрдВред

рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░


рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рдХреЙрд░реНрдкреЛрд░реЗрдЯ рд╣рд┐рдЯрд▓реИрдм рд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдмреЗ рдкрд░ рд▓реЗрдЦ рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд╣рд┐рдЯрд▓реИрдм рдХреЛ рдмрдВрджрд░реЛрдВ рдФрд░ рдордЧрд░рдордЪреНрдЫреЛрдВ рдХреЗ рд╕рд╛рде рддреИрдирд╛рдд рдХрд┐рдпрд╛ред рд╣рд╛рдВ, рдпрд╣ рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреАрддрд╛рд▓рд╛рдм рд╣реИ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдЧреАрддрд╛рд▓рд╛рдм рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХреЛрдИ рдХрдо рдЧрдВрднреАрд░ рдХрд╛рд░реНрдп рд╡рд╣рд╛рдВ рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


karcass


рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ, рдореИрдВрдиреЗ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ Node.js рдкрд░ рдмреИрдХрдПрдВрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдиреЗ рдПрдХ рд░реВрдкрд░реЗрдЦрд╛ рдХрд╛ рд░реВрдк рд▓рд┐рдпрд╛ - рдлрд╛рдЗрд▓реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯред рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдмрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдХреЙрдкреА рдХрд┐рдпрд╛ред рдпрд╣ рд╣рдореЗрд╢рд╛ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдЬрд╛ рд╕рдХрд╛, рдФрд░ рдореИрдВрдиреЗ karcass npm рдкреИрдХреЗрдЬ рдмрдирд╛рдпрд╛ (рдирд╛рдо рд╢рд╡ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕реА рд╕рд╛рдЗрдХрд┐рд▓ рдЙрддреНрд╕рд╛рд╣реА рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬреИрд╕рд╛ рдореИрдВрдиреЗ рдХрд┐рдпрд╛ рдерд╛), рдЬреЛ рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:


рдЕрдм рд╣рдореЗрдВ рд╕рдореВрд╣реЛрдВ, рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ, рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдХрд▓рд╛рдХрд╛рд░реЛрдВ рдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рднрдВрдбрд╛рд░рдг рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

TypeORM


"рдореИрдВ рдХреБрдЫ рд╕рдВрд╕реНрдерд╛рдПрдБ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБ ..."
- рдордиреЛрд╡рд┐рдЬреНрдЮрд╛рди рдордВрдЪ рдкрд░ рдЪрд░реНрдЪрд╛ рд╕реЗ

рдЪреВрдВрдХрд┐ рд╣рдореЗрдВ рдЧрд┐рдЯрд▓реИрдм рд╕реЗ рдбреЗрдЯрд╛ рдХреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рдмреАрдЪ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдореЗрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рддрд░рд╣ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдореИрдВрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрджреНрднреБрдд рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдЦреЛрдЬ рдХреА, рдЯрд╛рдЗрдкрдлреЙрд░реНрдо, рдЬреЗрдПрд╕ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдХреЗ рд▓рд┐рдП рдЕрджреНрднреБрддред рдпрд╣ рдЕрднреА рднреА рд╣рд░рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реАрдХреНрд╡рд▓ рдХреЛ рд╕рд┐рдВрд╣рд╛рд╕рди рд╕реЗ рдмрд╛рд╣рд░ рдХрд░рдиреЗ рдХрд╛ рд╣рд░ рдореМрдХрд╛ рд╣реИред

рджрд╕рд┐рдпреЛрдВ рдорд┐рдирдЯреЛрдВ рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ , рд╕рдореВрд╣реЛрдВ , рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдФрд░ рдХрдХреНрд╖рд╛рдПрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВред рдпрд╣рд╛рдБ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ:

import { Entity, PrimaryColumn, Column } from 'typeorm' @Entity({ name: 'group' }) export class Group { @PrimaryColumn('integer') public id!: number @Column('varchar') public name!: string @Column('varchar') public url!: string } 

рдФрд░ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдлрд┐рд░ рд╕реЗ рдПрдХ CreateMigrationCommand рд╕рд╣рд╛рдпрдХ рдмрд╛рдЗрдХ рдмрдирд╛рдИред рдпрд╣ рдХрдорд╛рдВрдб рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:


рдЕрдВрдХ рд╡рд░реНрдЧ рдореЗрдВ, рдЧреАрддрд╛рд▓рд╛рдм рд╕реЗ рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЙрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рдХрд╛рд░рдг рд╕рдВрдкреВрд░реНрдг рдЙрдкрджреНрд░рд╡ рд╢реБрд░реВ рд╣реБрдЖ, рдпрд╛рдиреА рдХрд┐ рдХрд╛рдирди рдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдп рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╕рдВрдХреЗрдд:

 export class Issue extends AbstractEntity { /* ... */ @Column('varchar', { name: 'kanban_status' }) public kanbanStatus?: 'new'|'planed'|'working'|'checking'|'done' @Column('int', { name: 'kanban_order' }) public kanbanOrder?: number } 

рд╣рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЪрд╛рд╣рд┐рдП


рдЬрдм рдореИрдВрдиреЗ рдкрд╣рд▓реА рдмрд╛рд░ GitLab рдХреЗ рд╕рд╛рде рдЕрдкрдирд╛ рдкрд░рд┐рдЪрдп рд╢реБрд░реВ рдХрд┐рдпрд╛, рддреЛ рдпрд╣ рдореБрдЭреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг ("рдирдлрд░рдд") рдЙрддреНрдкрд╛рдж рд▓рдЧрддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╣рд░ рджрд┐рди рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдореИрдВ рдХрд┐рддрдирд╛ рдЧрд▓рдд рдерд╛ред рддреЛ рдЗрд╕ рдмрд╛рд░ рдореИрдВ рд╣реИрд░рд╛рди рдерд╛ - рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ GitLab рдореЗрдВ рдПрдХ рдмрд╣реБрдд рд╕рдореГрджреНрдз рдПрдкреАрдЖрдИ рд╣реИ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдкрд▓рдмреНрдз рд▓рдЧрднрдЧ рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдЪрд╛рд░ рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдирд╛рдо рдЦреБрдж рдХреЗ рд▓рд┐рдП рдмреЛрд▓рддреЗ рд╣реИрдВ: / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ , / рд╕рдореВрд╣ , / рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ , / рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ /: рдЖрдИрдбреА / рдореБрджреНрджреЗ ред GitlabService GitLab рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рд╕рдВрдкрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛, рдФрд░ рдЕрдиреНрдп рд╡рд░реНрдЧ рдЗрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, GroupService рд╡рд░реНрдЧ рдХреЗ рдЕрджреНрдпрддрдирд╕рдореВрд╣ рдкрджреНрдзрддрд┐ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 export class GroupService extends AbstractService { /* ... */ public async updateGroups() { for (const data of await this.app.gitlabService.getGroups()) { // <=     GitlabService let group = await this.getGroup(data.id) if (!group) { group = this.groupRepository.create({ id: data.id, }) } group.name = data.name group.url = data.web_url await this.groupRepository.save(group) } } /* ... */ } 

рдЕрдкрдбреЗрдЯрдкреНрд░реЛрдЬреЗрдХреНрдЯрд╕реЛрдореИрдВрдб рдХрдорд╛рдВрдб рдЬрд┐рддрд╛рд▓рд╛рдм рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛, рдЬрд┐рд╕реЗ рдХрдВрд╕реЛрд▓ рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рд╣реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде рд▓реЙрдиреНрдЪ рдХрд░реЗрдЧрд╛:

 export class Application { /* ... */ protected initCron() { if (this.config.gitlab.updateInterval) { setInterval(async () => { if (!this.updateProjectsCommand) { this.updateProjectsCommand = new UpdateProjectsCommand(this) } await this.updateProjectsCommand.execute() }, this.config.gitlab.updateInterval * 1000) } } /* ... */ } 

рд╣рдо рдмреЛрд░реНрдб рдкрд░ рдХреЙрд▓рдореЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛, рд░рдВрдЧ рдФрд░ рдирд╛рдо рдХреЛ рд╣рд╛рд░реНрдбрдХреЛрдб рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ config.js рдореЗрдВ рдЕрдиреБрдХреВрд▓рди рдпреЛрдЧреНрдп рдмрдирд╛рдПрдВрдЧреЗред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдирдореЗрдВ рд╕реЗ рдкрд╛рдВрдЪ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП, рд╢рд╛рдпрдж рдХреЗрд╡рд▓ рджреЛ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ рдПрд╕рд┐рдб рдХрд╛ рд░рдВрдЧ:

 columns: [ { key: 'new', title: '', color: 'rgb(255, 255, 219)' }, { key: 'planed', title: '', color: 'rgb(236, 236, 191)' }, { key: 'working', title: ' ', color: 'rgb(253, 214, 162)' }, { key: 'checking', title: ' ', color: 'rgb(162, 226, 253)' }, { key: 'done', title: '', color: 'rgb(162, 253, 200)' }, ], 

рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХрдо рд╕реЗ рдХрдо рджреЛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрдиреНрдпрдерд╛ рдЖрд╡реЗрджрди рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред

рдореЛрд░реНрдЪреЗ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрд╛рд░реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░реЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ "рдХреЙрд▓рдо" рдореЗрдВ рдЫрд╛рдБрдЯреЗ:

рдЬрд╛рд░реА рдХрд░реЗрдВ
 export class IssueService extends AbstractService { /* ... */ public async getKanban() { let issues = await this.issueRepository.find({ where: { updatedTimestamp: MoreThanOrEqual(new Date().getTimestamp() - 60 * 60 * 24 * 30) }, order: { kanbanOrder: 'ASC', updatedTimestamp: 'DESC' }, }) const keys = this.app.config.columns.map(c => c.key) const result: { [key: string]: Issue[] } = {} for (let ki = keys.length - 1; ki >= 0; ki--) { const key = keys[ki] if (ki === keys.length - 1) { //        result[key] = issues.filter(i => i.closed) } else if (ki === 0) { // ,  ,    ,    result[key] = issues } else { result[key] = issues.filter(i => i.kanbanStatus === key) } issues = issues.filter(i => !result[key].includes(i)) //     } return result } /* ... */ } 

рдФрд░ рдПрдХ рдирд┐рдпрдВрддреНрд░рдХ рдЬреЛ рдирдП рдХрд╛рд░реНрдп рдкрджреЛрдВ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ:

рдЗрд╢реНрдпреВрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рджрд┐рдЦрд╛рдПрдВ
 export default class IssueController extends AbstractController { /* ... */ public async kanbanUpdate(data: IQueryData) { const keys = this.app.config.columns.map(c => c.key) for (const c of data.params as { key: string, title: string, color: string, issues: number[] }[]) { if (keys.indexOf(c.key) < 0) { continue } let index = 0 for (const i of c.issues) { index++ const issue = await this.app.issueService.getIssue(i) if (!issue) { continue } issue.kanbanStatus = c.key issue.kanbanOrder = index this.app.issueService.issueRepository.save(issue) } } } } 

Shtoshред рд╣рдо GitLab рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдПрдХрддреНрд░ рдХрд░рддреЗ рд╣реИрдВ, рдмреЛрд░реНрдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдпрд╣ рднреА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рдкрджреЛрдВ рдХреЛ рдХреИрд╕реЗ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдПред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдмрдЪреА рд╣реИ рд╡рд╣ рд╣реИ рдмреЛрд░реНрдб рдХреЛ рдЦреБрдж рдмрдирд╛рдирд╛ред рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╕реЗ рд▓реИрд╕ рд╣реИрдВ:

Vue CLI - рдПрдХ рд╣рдЬрд╛рд░ рд╢рдмреНрджреЛрдВ рдХреЗ рдмрдЬрд╛рдп



TSX


рд░рд┐рдлреИрдХреНрдЯрд┐рдВрдЧ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдмрдЧреНрд╕, рд▓рд╛рдЗрдирд┐рдВрдЧ рдФрд░ рдорди рдХреА рдЕрдиреНрдп рд╢рд╛рдВрддрд┐ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо tsx рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ Vue.js рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ * рд▓рдЧрднрдЧ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдмреЛрд░реНрдб рдореЗрдВ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдШрдЯрдХ, рдХрд╛рд░реНрдп рдкреНрд░рд╕реНрддреБрддрд┐ рдХрд╛ рдШрдЯрдХ:

рдХреЛрдб рдЬрд╛рд░реА рдХрд░реЗрдВ .tsx
 import { Vue, Component, Prop, Watch } from 'vue-property-decorator' import './Issue.css' import { CreateElement, VNode } from 'vue' interface IIssue { groupId: number groupName: string groupUrl: string projectName: string projectUrl: string url: string title: string executor: { color: string, name: string } spent: number estimate: number } @Component export default class extends Vue { @Prop() public issue!: IIssue public issueValue!: IIssue public selectUser = false @Watch('issue', { immediate: true }) public onIssueChange() { this.issueValue = this.issue } // eslint-disable-next-line @typescript-eslint/no-unused-vars public render(h: CreateElement): VNode { return <div class="kvcIssue"> <div class="kvciTitle"> { this.issueValue.groupId ? <small><a href={ this.issueValue.groupUrl } target="_blank"> { this.issueValue.groupName } </a> / </small> : undefined } <a href={ this.issueValue.projectUrl } target="_blank">{ this.issueValue.projectName }</a> </div> <div class="kvciText"><a href={ this.issueValue.url } target="_blank">{ this.issueValue.title }</a></div> <div class={ ['kvciExecutor', this.issueValue.executor ? '' : 'none'] }> <span class="timeTd"> <span title=" ">{ this.issueValue.spent.time() }</span> / <span title=" "> { this.issueValue.estimate.time() }</span> </span> { this.issueValue.executor ? <span class="kvcieUser" style={ { background: this.issueValue.executor.color } }> { this.issueValue.executor.name } </span> : <span class="kvcieSelect"> </span> } </div> </div> } } 

рдпрд╣ рдШрдЯрдХ рдХрд╛рд░реНрдп рдкрдЯреНрдЯреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдХрд╛рд░реНрдп рдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдордп рдФрд░ рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рд╣реИ:


рдЗрд╕рдореЗрдВ Column.tsx рдФрд░ Kanban.tsx рдШрдЯрдХ рднреА рд╣реИрдВред рдХреЗрд╡рд▓ рддреАрди рдШрдЯрдХ рдмреЛрд░реНрдб рдкрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ:


Vue.Draggable , рдЬрд┐рд╕рдХреЗ рдкреИрд░ SortableJS рд╕реЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рдмреЛрд░реНрдб рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдпрд╣ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдВрдд рд╕рд░рд▓ рд╣реИ:

 import Draggable from 'vuedraggable' /* ... */ export default class extends Vue { /* ... */ public render(h: CreateElement): VNode { /* ... */ <Draggable class="kvcIssues" vModel={ this.issuesValue } group={ { name: 'issues', pull: true, put: true } } onEnd={ this.onDrag } onAdd={ this.onDrag } > { this.issuesValue.map(i => <Issue key={ i.id } issue={ i } />) } </Draggable> /* ... */ } } 

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдЕрдкрдирд╛ рд░рдВрдЧ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓реЙрдЧрд┐рди рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ - рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рдмреАрдЪ, рдЖрдк рдЬрд▓реНрджреА рд╕реЗ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред "рдмрд╣реБрдЖрдпрд╛рдореА" рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ: рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рд╣рд╛рдереЛрдВ рд╕реЗ рд░рдВрдЧ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдпрд╛ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЗрд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ред

рдореБрдЭреЗ рдЕрдкрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рджреЗрдВ рдФрд░ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреМрди рд╕рд╛ рд░рдВрдЧ рд╣реИ


рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд░реНрдЧ рдХрд╛ рд░рдВрдЧ рдкрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд░рдВрдЧ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрддрд╛ рд╣реИред рдореИрдВрдиреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдмреИрдХрдПрдВрдб рдкрд░ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдкреВрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд╕рд╛рдордиреЗ рдЦреАрдВрдЪрдирд╛ рдЕрдкрд░рд╛рдз рд╣реИред рдФрд░ рдпрд╣ рддрдм рдФрд░ рд╕рд╣реА рд╣реИ рдЬрдм рдкреАрда, рдФрд░ рд╕рд╛рдордиреЗ рдирд╣реАрдВ, рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ:

 export class User extends AbstractEntity { /* ... */ public get color() { const hash = crypto.createHash('md5').update(this.username).digest() //  md5       .     -   . const result: number[] = [] for (let i = 0; i < 3; i++) { result.push(Math.round(200 - hash[i] / 255 * 150)) //      ,     ,       } return `rgb(${result.join(', ')})` } } 

рдЬреЛ рд▓реЛрдЧ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЙрдирдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рд░рдВрдЧ рд╣реИ, рдореИрдВ рдХреЛрдбрдкреЗрди рдкрд░ рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдХрд╛рдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд▓рд╕реА рдирд╣реАрдВ рдерд╛ред

рд╡рд╣ рд╕рдм


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдордВрдЧрд▓рд╡рд╛рд░ рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛:

рдЖрд░: рдареАрдХ рд╣реИ, рдмреЛрд░реНрдб рдХреИрд╕реЗ рддреИрдпрд╛рд░ рд╣реИ? ..
рдореИрдВ: рд╣рд╛рдБ, рдпрд╣рд╛рдБред
R: рдУрд╣, рдЕрдЪреНрдЫрд╛!

рдореЗрд░реЗ "рдХрд╛рд░реНрдпрджрд┐рд╡рд╕" тАЛтАЛрдХрд╛ рдкрд░рд┐рдгрд╛рдо рдпрд╣рд╛рдБ рд╣реИ: https://github.com/onlanta/kanban ред рдЖрдк рдЗрд╕реЗ рди рдХреЗрд╡рд▓ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЫреВ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╡рд╣рд╛рдВ рдирд┐рд░реНрджреЗрд╢)ред рдФрд░ рдЖрдк рдЗрд╕ рдкрд░ рд╣рд┐рдЯрд▓реИрдм рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реЗ рд╕рдордп рдХрд╛ рдЯреНрд░реИрдХрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдордиреЗ рдХрдВрдкрдиреА рдореЗрдВ рдХрд┐рдпрд╛ рдерд╛ред

рдореИрдВрдиреЗ рдпрд╣ рдиреЛрдЯ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛? рдпрд╣ рдореЗрд░реА рдкреЗрд╢реЗрд╡рд░ рдЧрддрд┐рд╡рд┐рдзрд┐ рдореЗрдВ рд╣рд╛рд▓ рдХреЗ рдЙрдЬреНрдЬреНрд╡рд▓ рдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдЬрдм рдХрд╛рд░реНрдп рдорд╣рддреНрд╡рдкреВрд░реНрдг, рджрд┐рд▓рдЪрд╕реНрдк рдерд╛, рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрд╛рдлреА рд╕рд░рд▓ рдерд╛, рдФрд░ рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдЖрд╕рд╛рди рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд┐рдХрд▓рд╛ред рдореИрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдкрдиреЗ рдЕрднреНрдпрд╛рд╕ рд╕реЗ рд╕рдорд╛рди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдпрд╛рдж рдХрд░реЗрдВред

Source: https://habr.com/ru/post/hi462855/


All Articles